将数据插入 MySQL 数据库时使用 PHP 替换 CSV 文件中的空值
Posted
技术标签:
【中文标题】将数据插入 MySQL 数据库时使用 PHP 替换 CSV 文件中的空值【英文标题】:Replacing empty values in a CSV file using PHP when inserting data into a MySQL database 【发布时间】:2021-12-08 02:03:20 【问题描述】:我目前遇到一个问题,当我尝试使用 php 将 CSV 文件中的数据插入 mysql 数据库时,我收到一个由 CSV 文件中的空字段引起的错误。
在每行至少有一个空字段的数据中,它会产生错误,并且由于空字段而不会将整行插入数据库。
我想知道是否有人知道如何在 CSV 文件中查找每个空字段并在插入之前填充它们(“0”表示空 int 字段,“N/A”表示空 varchar 字段)而不通过 CSV文件并手动填写数据。
将数据插入数据库的代码
foreach($gymarr as $row)
$day = $row[0];
$routine= $row[1];
$time= $row[2];
$type= $row[3];
$run= $row[4];
$weights= $row[5];
$tally= $row[6];
$sqlinsert = "INSERT INTO Gym (day, routine, time, type, run, weights, tally)
VALUES ('$day', '$routine', $time, '$type', '$run', '$weights', tally)";
$result = $conn->query($sqlinsert);
【问题讨论】:
究竟是什么错误?如果您使用准备好的语句和参数来构建查询,这将更加可靠 - 这样您就不会容易受到数据中撇号之类的影响,并且也可能不太容易受到空/空单元格的影响。 phpdelusions.net/mysqli 包含简单示例。 如果您输入到数据库中的字段始终具有默认值,那么您最好在数据库架构中的每个字段上设置一个默认值 - dev.mysql.com/doc/refman/8.0/en/data-type-defaults.html。您可以在插入时只使用三元... "$day = $row[0] ?? null;" 发布您遇到的确切错误,因为没有它我们没有完整的图片。您是否将表属性设置为允许空值? “您的 SQL 语法有错误;请查看与您的 MariaDB 服务器版本相对应的手册,以在第 4 行的 ''50kg')' 附近使用正确的语法”我已尝试手动填写在此部分附近的数据中,它是空的并且它解决了问题,这就是我知道问题是 CSV 文件中的空单元格的方式 目前尚不完全清楚导致问题的原因,因为我们看不到查询的其余部分。如果你在运行之前转储$sqlinsert
,我们可以看到整个事情并且更容易发现错误。但同样,我怀疑这无论如何都可以通过使用参数来解决 - 请也尝试一下。
【参考方案1】:
也许这种方式对你有用:
$day = $row[0] !== "" ? $row[0] : "n/a";
$routine= $row[1] !== "" ? $row[1] : "n/a";
$time= $row[2] !== "" ? $row[2] : "n/a";
$type= $row[3] !== "" ? $row[3] : "n/a";
$run= $row[4] !== "" ? $row[4] : "n/a";
$weights= $row[5] !== "" ? $row[5] : "n/a";
$tally= $row[6] !== "" ? $row[6] : "n/a";
如果需要,您可以将“n/a”替换为“0”。
【讨论】:
我还必须将 real_escape_string 添加到某些字段,因为有些字符会导致 SQL 语法出现问题。是否也可以将 real_escape_string 添加到您刚刚发送的代码中?当前代码:$run= $conn->real_escape_string($row[4]); @SnrJava 当然 - 转义字符串总是一个好主意。 我不确定如何在同一行中实际格式化它,还是需要与您发送的代码分开完成? 警告:empty
可能会令人惊讶! '0'
是空的。检查空字符串$day === ""
等更安全...
@Fravadona 你说得对!更新了我的答案!【参考方案2】:
空值对 sql 插入有效。错误
“您的 SQL 语法有错误;请查看手册 对应于您的 MariaDB 服务器版本,以便使用正确的语法 在第 4 行的“'50kg')' 附近”
意味着值本身由于语法而破坏了您的查询。如果您绑定这些值,那么数据库将分离查询和值,并且您的源不应再破坏这些值。 mysql允许空''
。
解决问题的正确、最佳和最安全的方法是使用绑定参数。几年前我写的以下函数为我简化了这种类型的工作,它们可以防止 sql 被值污染。
功能:
function dbConnect($dbname,$username,$password,$servername = "localhost")
if(empty($dbname) || empty($username) || empty($password)) return "Undefined database, username or password.";
try
$conn = new PDO("mysql:host=$servername;charset=utf8;dbname=".$dbname, $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
$conn->setAttribute(PDO::MYSQL_ATTR_LOCAL_INFILE, true);
return $conn;
catch(PDOException $e)
return "Connection failed: " . $e->getMessage();
function dbQuery($conn,$sql="", $parameters=array(),$constant = PDO::FETCH_ASSOC)
try
$stmt = $conn->prepare($sql);
catch(PDOException $e)
return $e;
foreach($parameters as $key=>$value) $stmt->bindValue( $key+1, $value);
try
$stmt->execute();
if ($stmt->columnCount() > 0)
$result = $stmt->fetchAll($constant); //in cases of select something, return the rows.
else
$result = $stmt->rowCount();//in case of update/insert/delete statements: get number of rows affected
catch(PDOException $e)
$result = $e->getMessage();
return $result;
代码:
$conn = dbConnect($dbname,$username,$password,$servername);//you have to populate these values yourself
foreach($gymarr as $row)
$sql = "INSERT INTO Gym (day, routine, time, type, run, weights, tally)
VALUES (?, ?, ?, ?, ?, ?, ?)";
$result = dbQuery($conn, $sql,$row);//row is any flat, two dimensional array. It must have the same number of values as the number of '?' in your sql for each one to bind to and in the order that those columns appear in your query.
如果您更喜欢 MySQLi 作为数据库连接,请参阅 https://www.w3schools.com/php/php_mysql_prepared_statements.asp。
【讨论】:
以上是关于将数据插入 MySQL 数据库时使用 PHP 替换 CSV 文件中的空值的主要内容,如果未能解决你的问题,请参考以下文章