致命错误:未捕获的PDOException:列不能为空(但不为空...)

时间:2018-10-03 03:07:47

标签: php mysql pdo prepared-statement fgetcsv

每次我的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 => $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 ...都没有...

2 个答案:

答案 0 :(得分:0)

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

  如果提供了无效的句柄,则

fgetcsv()返回 NULL ,对于其他错误(包括文件结尾),则返回 FALSE

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

例如

$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);

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

答案 1 :(得分:-1)

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

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

您丢失了传递给:的密钥的PDOStatement::execute部分