【问题标题】:Proper use of NULL in mysql query from php在 php 的 mysql 查询中正确使用 NULL
【发布时间】:2013-08-31 09:42:41
【问题描述】:
$ETA_time =  strtotime($arrivals[$i]["operationalTimes"]["estimatedGateArrival"]["dateLocal"]);
if (!$ETA_time) {
    $ETA = 'NULL';
} else {
    $ETA = strftime("%Y-%m-%d %H:%M:%S", $ETA_time);
}

$STA_time   = strtotime($arrivals[$i]["operationalTimes"]["scheduledGateArrival"]["dateLocal"]);
if (!$STA_time) {
    $STA = 'NULL';
} else {
    $STA = strftime("%Y-%m-%d %H:%M:%S", $STA_time);
}

$ATA_time = strtotime($arrivals[$i]["operationalTimes"]["actualGateArrival"]["dateLocal"]);
if (!$ATA_time) {
    $ATA = 'NULL';
} else {
    $ATA = strftime("%Y-%m-%d %H:%M:%S", $ATA_time);
}

$query="INSERT INTO `Schedule` (`ETA`,`STA`,`ATA`)
            VALUES('".$ETA."','".$STA."','".$ATA."');";
$result=run_query($query);

相关的MySQL DB表:

CREATE TABLE `Schedule` (
  `id` smallint(6) NOT NULL AUTO_INCREMENT,
  `STA` datetime DEFAULT NULL,
  `ETA` datetime DEFAULT NULL,
  `ATA` datetime DEFAULT NULL,
);

查询var_dump:

INSERT INTO `Schedule` (`ETA`,`STA`,`ATA`) VALUES('2013-08-28 12:30:00','NULL','NULL');

错误信息是:

Incorrect datetime value: 'NULL' for column 'STA' at row 1

【问题讨论】:

  • NULL 是关键字,而不是字符串,不应单引号。 VALUES('2013-08-28 12:30:00',NULL,NULL);
  • 因为传递NULL作为字符串不是NULL,所以传递空字符串或者关键字本身
  • 每个 SQL 错误都有一个编号。你得到的错误号是多少(如果不是两个数字)?您不清楚错误消息的哪一部分(您已发布)?

标签: php mysql null


【解决方案1】:

NULL 是一个特定的值,而不是字符串文字。它应该直接传递给查询,即

INSERT INTO `Schedule` (`ETA`,`STA`,`ATA`)
    VALUES ('2013-08-28 12:30:00', NULL, NULL);

这意味着你的 PHP 代码应该处理它而不是包含 NULL-s:

$timeFormatAndNull = function ($format) {
    return function($time) use ($format) {
        $time = strtotime($time);
        return $time ? strftime($format, $time) : 'NULL';
    };
};


$operationalLocalDate = function($arrivals, $callback) {
    return function($i, $date) use ($arrivals, $callback) {
        return $callback(
           $arrivals[$i]["operationalTimes"][$date]["dateLocal"])
        );
    };
};

$formatTime = $operationalLocalDate(
    $arrivals
    $timeFormatAndNull("'%Y-%m-%d %H:%M:%S'")
);

$query = sprintf(
    "INSERT INTO `Schedule` (`ETA`,`STA`,`ATA`) VALUES (%s, %s, %s);"
    , $formatTime($i, "estimatedGateArrival")
    , $formatTime($i, "scheduledGateArrival")
    , $formatTime($i, "actualGateArrival")
);

【讨论】:

  • @harke - 感谢您的精彩编辑。老实说 - 我为你的编辑感到羞耻。
  • 实际上正如问题所述,NULL 也是默认值,所以在我看来,更正确的方法是根本不使用 INSERT 传递 NULL 值,因为它们不需要(我无法想象这是投反对票的原因)。但这需要一种不同的方式来创建 SQL 查询。
【解决方案2】:

出现该错误消息的原因是因为您在 日期时间 数据类型。

当您希望列 STAATA 的值为 NULL 时,请传递不带单引号的 NULL 值。值周围的单引号使其成为文字字符串。

INSERT INTO `Schedule` (ETA, STA, ATA) 
VALUES ('2013-08-28 12:30:00', NULL, NULL)

作为旁注,如果变量的值(s)来自外部,则查询很容易受到SQL Injection 的攻击。请看下面的文章,了解如何预防。通过使用PreparedStatements,您可以摆脱在值周围使用单引号。

【讨论】:

  • +反对那个-v
猜你喜欢
  • 2014-09-13
  • 2017-08-18
  • 1970-01-01
  • 2014-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多