我有一个要写入 mysql 表的 csv 文件。
file.csv
id,name,age,job
5,John Smith,34,Janitor
7,Jane Smith,,Teacher
9,Jim Bob,23,Coach
table
CREATE TABLE `table` (
`id` smallint(3) unsigned NOT NULL,
`name` varchar(30) DEFAULT NULL,
`age` tinyint(3) unsigned DEFAULT NULL,
`job` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
我的问题是 Jane Smith 年龄的空值作为 0 插入到我的 MySQL 表中,尽管 age
默认为 NULL。我正在使用以下 fgetcsv() PHP。
$f = '/home/file.csv';
$file = fopen($f,'r');
fgetcsv($file); // skips 1st line with headers
while (($data = fgetcsv($file,0,",")) !== FALSE) {
if (array(null) !== $data) {
$id = $data[0];
$name = $data[1];
$age = $data[2];
$job = $data[3];
$bind_params = array(
':id' => $id,
':name' => $name,
':age' => $age,
':job' => $job
);
$stmt = $conn->prepare("INSERT INTO table (id, name, age, job) VALUES (:id, :name, :age, :job)");
$stmt->execute($bind_params);
}
}
我读过 http://php.net/manual/en/function.fgetcsv.php和 https://dev.mysql.com/doc/refman/5.5/en/load-data.html最后,但我无法弄清楚。我在 , 之间替换了“NULL”、“”、“\N”、NULL 和\N,但我没有得到任何不同的结果。我还尝试过显式键入 fgetcsv() 的可选参数,如 php.net 上的示例所示。
array fgetcsv ( resource $handle [, int $length = 0 [, string $delimiter = "," [, string $enclosure = '"' [, string $escape = "\\" ]]]] )
我错过了什么!?谢谢。
附加信息: 我更喜欢这是一个 php/fgetcsv 解决方案而不是一个纯 MySQL 解决方案,因为上面的数据只是一个快照(总共有 99 列)并且许多列在被插入到其他表之前是输入到 php 计算中。
最佳答案
csv 中的空值被 PHP 的 fgetcsv() 读取为空字符串,而不是真正的 NULL 值。在绑定(bind)变量(对于 PDO)并插入 MySQL 表之前,仅将那些空字符串变量(通过 if() 语句)重新分配给 NULL 值。
从@u_mulder 输入后,我将每个变量包装在一个查找空字符串的 if 语句中,如果空字符串为真,则为该变量赋值 = null。由于我有 99 列,我将把它放入 for() 循环中以获取所有列。
for ($i=0; $i<=99; $i++) {
if($data[$i] === "") { $data[$i] = null; }
}
我实现了这个,它完全符合我最初的需要。
编辑 我更新了代码以使用 === 而不仅仅是 ==。我发现双等号将零转换为空值。因为我只想要空字符串,所以需要第三个等号。
关于php - 使用 fgetcsv() 将数据导入 mysql 并将空值存储为零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25221093/