空的DATETIME值在MySQL中存储为0000-00-00 00:00:00而不是NULL


Empty DATETIME value stored as 0000-00-00 00:00:00 instead of NULL in MySQL

我有可选的日期和时间表单字段,这些字段组合在一起形成一个DATETIME友好的字符串,然后将其发送到MySQL数据库。相关的 MySQL 列数据类型为 DATETIME ,默认值为 NULL 。当日期和时间字段完成时,它会正确保存;但是,当这些可选表单字段为空时,日期时间将存储为 0000-00-00 00:00:00 而不是 NULL 。它需要存储为NULL,我不知道为什么不这样做。这是我的代码:

$Date_Query_Received1   = mysqli_real_escape_string($conn, $_POST['Date_Query_Received']);
$Date_Query_Received2   = implode("-", array_reverse(explode("/", $Date_Query_Received1)));
$Time_Query_Received1   = mysqli_real_escape_string($conn, $_POST['Time_Query_Received']);
$Time_Query_Received2   = $Time_Query_Received1.':00';
if (empty($_POST['Date_Query_Received']) || empty($_POST['Time_Query_Received'])) {
    $Date_Query_Received = NULL;
    $Time_Query_Received = NULL;
} else {
    $Date_Query_Received = $Date_Query_Received2;
    $Time_Query_Received = $Time_Query_Received2
}
$Date_Time_Query_Received = $Date_Query_Received.' '.$Time_Query_Received;
mysqli_query($conn, "INSERT INTO log (Date_Time_Query_Received) VALUES ('$Date_Time_Query_Received')";

表单日期采用 DD/MM/YYYY 格式,因此implode(...array_reverse(...))转换为 MySQL 友好的 DATETIME YYYY-MM-DD 格式。这同样适用于将":00"附加到时间值,因为表单字段 jQuery 时间选择器仅针对 hh:mm 设置 - 不需要秒。

也许它与 SQL 语句中$Date_Time_Query_Received引号有关;但是如果没有引号,查询就会失败。

因此,如果您查看查询,您正在尝试将日期列设置为字符串' '这显然不会让 MySQL 满意。不过,这是一个非常宽容的数据库,并且默认为DATETIME列的回退,即0000-00-00 00:00:00

那么,如何将空值从 PHP 传递给数据库呢?尝试使用预准备语句,如下所示:

if (empty($_POST['Date_Query_Received']) || empty($_POST['Time_Query_Received'])) {
    $Date_Time_Query_Received = NULL;
} else {
    $Date_Query_Received2 = implode("-", array_reverse(explode("/", $_POST['Date_Query_Received'])));
    $Time_Query_Received2 = "$_POST[Time_Query_Received]:00";
    $Date_Time_Query_Received = "$Date_Query_Received2 $Time_Query_Received2";
}
$stmt = $conn->prepare("INSERT INTO log (Date_Time_Query_Received) VALUES (?)");
$stmt->bind_param("s", $Date_Time_Query_Received);
$stmt->execute();

除了更容易传递 null 值之外,您还可以比使用 mysqli_real_escape_string() 更有效地保护自己免受 SQL 注入攻击。