我在MySQL中的某些列上创建了一个带有NOT NULL
约束的表。然后在PHP中我编写了一个插入数据的脚本,带有插入查询。当我省略这个insert语句中的NOT NULL
列之一时,我会期望来自MySQL的错误消息,我希望我的脚本失败。相反,MySQL在NOT NULL
字段中插入空字符串。在其他省略的字段中,数据为NULL,这很好。有人能告诉我这里做错了吗?
我正在使用此表:
CREATE TABLE IF NOT EXISTS tblCustomers (
cust_id int(11) NOT NULL AUTO_INCREMENT,
custname varchar(50) NOT NULL,
company varchar(50),
phone varchar(50),
email varchar(50) NOT NULL,
country varchar(50) NOT NULL,
...
date_added timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (cust_id)
) ;
这个插入声明:
$sql = "INSERT INTO tblCustomers (custname,company)
VALUES ('".$customerName."','".$_POST["CustomerCompany"]."')";
$res = mysqli_query($mysqli, $sql);
或使用绑定变量:
$stmt = mysqli_prepare($mysqli, "INSERT INTO tblCustomers (custname,company, email, country) VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'ssss', $customerName, $_POST["CustomerCompany"], $_POST["CustomerEmail"], $_POST["AddressCountry"]);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
答案 0 :(得分:16)
如果您确定没有使用显式默认值,请检查严格模式:
SELECT @@GLOBAL.sql_mode;
SELECT @@SESSION.sql_mode;
MySQL Data Type Default Values
从MySQL 5.0.2开始,如果是一列 定义包括没有明确的 DEFAULT值,MySQL决定了 默认值如下:
如果列可以取NULL作为 值,该列定义为 显式DEFAULT NULL子句。这是 与5.0.2之前相同。
如果列不能为NULL 值,MySQL定义列 没有明确的DEFAULT子句。对于数据 输入,如果是INSERT或REPLACE 声明中没有任何价值 列,或UPDATE语句集 列为NULL,MySQL处理 列根据SQL模式而定 当时效果:
如果未启用严格的SQL模式,MySQL会将列设置为 列的隐式默认值 数据类型。
如果启用了严格模式,则事务表会发生错误 并且该声明被回滚。对于 非交易表,一个错误 发生,但如果发生这种情况 a的第二行或后续行 多行语句,前面的 将插入行。
答案 1 :(得分:4)
你做错了是使用字符串而不是使用绑定参数来构建查询。
除了SQL注入漏洞之外,即使在数据库看到它们之前,空值也会被转换为空字符串。
$x = null;
print_r("VALUES ('$x', 42)");
输出:
VALUES ('', 42)
换句话说,您正在插入一个空字符串,而不是NULL。要插入NULL,您需要编写此代码:
VALUES (NULL, 42)
如果您使用绑定参数,那么您将不会遇到此问题,作为奖励,您的网站将不会有这么多安全漏洞。我建议你阅读this question的答案,并按照那里的建议。这将解决您的直接问题,并提高您网站的安全性。
答案 2 :(得分:1)
我同意Mark Byers - 你的php对你想要的行为不正确。
Re:Mark对绑定参数的评论,请查看PDO in PHP
如果您仍然不想使用参数,可以尝试以下方法:
if (isset($customerName) && $customerName != '')
{
$c = '\'' . $customerName . '\'';
} else {
$c = 'null';
}
if (isset($_POST['CustomerCompany']) && $_POST['CustomerCompany'] != '')
{
$cc = '\'' . $_POST['CustomerCompany'] . '\'';
} else {
$cc = 'null';
}
$sql = 'INSERT INTO tblCustomers (custname,company)
VALUES ('.$c.','.$cc.')';
编辑:您是否考虑过只检查您的PHP代码以确保值不是空/空?这样你就可以避免完全访问数据库(基于我对你的评论的解释)?不是MySQL行为的答案,但可能会解决您的问题。