为什么PHP PDO忽略NOT NULL约束?

jecbmhm3  于 2023-10-15  发布在  PHP
关注(0)|答案(1)|浏览(109)

我在PHP中使用PDO将值插入到MariaDB中。但是,当我违反NOT NULL约束时,什么也不会发生。我希望在这种情况下抛出一个异常。
我是这样创建表的:

CREATE TABLE person (
    id INT auto_increment NOT NULL,
    firstname varchar(255) NULL,
    lastname varchar(255) NULL,
    telephone varchar(255) NULL,
    alias1 varchar(255) NOT NULL,
    alias2 varchar(255) NULL,
    CONSTRAINT PRIMARY KEY (id)
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_general_ci;

下面是我用于测试的PHP脚本:

<?php

$conn = new PDO(
    'mysql:host=localhost;dbname=tibsi-data', 'root', '',
    array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")
);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$conn->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);

try {
    $stm = $conn->prepare("INSERT INTO person (firstname) VALUES (:firstname)");
    $stm->bindValue(':firstname', 'Mike');

    $success = $stm->execute();
    if (!$success) {
        throw new Exception($stm->errorInfo()[2]);
    }
    $stm->closeCursor();

    $insertId = $conn->lastInsertId();

    header('HTTP/1.1 200 OK');
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode(array('id' => $insertId));
    exit;
} catch (Exception $e) {
    header('HTTP/1.1 500 Internal Server Error');
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode(array('error' => $e->getMessage()));
    exit;
} catch (Error $e) {
    header('HTTP/1.1 500 Internal Server Error');
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode(array('error' => $e->getMessage()));
    exit;
}

正如你所看到的,alias1没有默认值,我在我的alias1语句中省略了它。当我使用SQL脚本尝试同样的事情时,我确实得到了一个错误。我希望这在PHP中抛出一个异常,导致500响应。相反,它使用alias1的空字符串插入行。我从来没有把它设为默认值。是否有一些属性可以设置以获得我想要的行为?

biswetbf

biswetbf1#

参见https://mariadb.com/kb/en/null-values/
如果将NULL值单行插入到声明为NOT NULL的列中,则将返回错误。但是,如果SQL模式不是严格的(在MariaDB 10.2.3之前是默认的),如果NULL值被多行插入到声明为NOT NULL的列中,则将插入列类型的隐式默认值(而不是表定义中的默认值)。对于字符串类型,隐式默认值为空字符串,对于数字、日期和时间类型,隐式默认值为零。
从MariaDB 10.2.4开始,默认情况下这两种情况都会导致错误。
如果sql_mode设置严格模式,则最后一条语句适用。严格模式在MariaDB 10.2.4及更高版本中默认设置为打开,但您可能已经更改了该选项。参见https://mariadb.com/kb/en/sql-mode/
我不知道为什么文档中特别提到多行插入。如果您插入一个单行并且未启用严格模式,也会发生同样的情况。

相关问题