【问题标题】:Fatal error: Uncaught PDOException: Column cannot be null (BUT it isn't null...)致命错误:未捕获的 PDOException:列不能为空(但它不为空...)
【发布时间】:2018-10-03 03:07:46
【问题描述】:

每次运行 PHP 脚本时都会遇到致命错误。尽管如此,所有数据仍然上传到数据库。当$values[0] 回显时,没有NULL 值作为错误状态,一切正常。我很困惑。

错误

[02-Oct-2018 19:59:54 America/Vancouver] PHP Warning:  Invalid argument supplied for foreach() in /home1/antonfa1/public_html/trading-history/process.php on line 22
[02-Oct-2018 19:59:54 America/Vancouver] PHP Fatal error:  Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'trade_date' cannot be null in /home1/antonfa1/public_html/trading-history/process.php:48
Stack trace:
#0 /home1/antonfa1/public_html/trading-history/process.php(48): PDOStatement->execute(Array)
#1 {main}
  thrown in /home1/antonfa1/public_html/trading-history/process.php on line 48

奇怪的是我昨天似乎没有收到这个警告和错误,所以我注释掉了我从那时起所做的所有修改,但问题仍然存在。

脚本

include 'includes/connect.php';
$stri = 'INSERT INTO trades (trade_date, trade_time, trade_datetime, trade_transaction, trade_symbol, trade_status, trade_quantity, trade_filled, trade_price, trade_value) VALUES (:date, :time, :datetime, :transaction, :symbol, :status, :quantity, :filled, :price, :value)';

$file = fopen($_SESSION['file'], 'r');

while (!feof($file)) {
    
  $values = [];
  
  foreach (fgetcsv($file) as $key => $value) {
    array_push($values, $value);
  }
  
  echo $values[0] . '<br>';
  
  $stat = $conn->prepare($stri);
  $stat->execute([
    'date' => $values[0],
    'time' => $values[1],
    'datetime' => $values[2],
    'transaction' => $values[3],
    'symbol' => $values[4],
    'status' => $values[5],
    'quantity' => $values[6],
    'filled' => $values[7],
    'price' => $values[8],
    'value' => $values[9],
  ]);
}

fgetcsv($file) as $key =&gt; $value 真的是无效参数吗?这是可能导致此“错误”错误的原因吗?我昨天没有收到这个警告:/

回声

2018-10-02
2018-10-02
2018-10-02
2018-10-02
2018-10-02
2018-10-02
2018-10-02
2018-10-02
2018-10-02
2018-10-02
2018-10-02
2018-10-02
2018-10-02
2018-10-02

所有数据点都在那里,没有一个是NULL...

【问题讨论】:

  • “fgetcsv($file) as $key => $value 真的是一个无效的参数吗?” returns false due to it being at the end of the file。这是您在使用fgetcsv()时需要检查的内容@
  • @Phil 为什么会在到达文件末尾后执行foreach 循环?
  • 因为你告诉它。
  • 看看这个例子~php.net/manual/…。您可以(并且应该)以与使用 feof() 相同的方式使用 fgetcsv()
  • 仅供参考,MySQL 有一个用于导入 CSV 数据的特定工具,它可能更易于使用。见dev.mysql.com/doc/refman/8.0/en/load-data.html

标签: php mysql pdo prepared-statement fgetcsv


【解决方案1】:

您的问题是fgetcsv() 在到达文件末尾时返回false...

fgetcsv() 如果提供了无效句柄,则返回 NULL,如果其他错误(包括文件结尾)返回 FALSE

您可以像使用feof() 一样使用fgetcsv(),只在有记录可找到时循环。

例如

$stri = <<<_SQL
INSERT INTO trades (
  trade_date, 
  trade_time, 
  trade_datetime, 
  trade_transaction, 
  trade_symbol, 
  trade_status, 
  trade_quantity, 
  trade_filled, 
  trade_price, 
  trade_value
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
_SQL; // note the positional placeholders

$stat = $conn->prepare($stri); // prepare once, not in a loop
$file = fopen($_SESSION['file'], 'r');

while($values = fgetcsv($file)) { // EOF will return false and exit the loop
    if (count($values) === 10) {
        echo $values[0] . '<br>';
        $stat->execute($values);
    } else {
        echo 'Skipping invalid record';
    }
}
fclose($file);

如果使用位置占位符,则无需为准备好的语句构造关联数组。

【讨论】:

  • 不知道谁投了你的票。在我尝试在您链接的 php 文档中举例说明后,我会立即尝试
  • 所以我从手册while (($row = fgetcsv($file)) !== FALSE) { $num = count($row); for ($c=0; $c &lt; $num; $c++) { echo $row[$c] . "&lt;br /&gt;\n"; } }得到了一个工作版本@
  • @Anthony 我已经更新了我的答案以添加更多检查,例如 $values 数组中的 10 条记录
  • 真的有必要像这样格式化$stri变量的值吗?
  • 漂亮。非常感谢你的帮助!!!真的很感激。令人失望的是有人会否决实际答案,但有点典型的 SO 哈哈
【解决方案2】:

您的 PDO 参数需要像这样传递:

$statement->execute([
    ':foo' => 1,
    ':bar' => '2001-01-01',
    ':baz' => 42
 ]);

您缺少传递给PDOStatement::execute 的密钥的: 部分

【讨论】:

猜你喜欢
  • 2021-06-02
  • 2015-07-10
  • 2017-06-12
  • 1970-01-01
  • 2019-12-05
  • 1970-01-01
  • 2018-07-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多