MySQL ignores the NOT NULL constraint

拥有回忆 提交于 2019-12-17 16:44:23

问题


I have created a table with NOT NULL constraints on some columns in MySQL. Then in PHP I wrote a script to insert data, with an insert query. When I omit one of the NOT NULL columns in this insert statement I would expect an error message from MySQL, and I would expect my script to fail. Instead, MySQL inserts empty strings in the NOT NULL fields. In other omitted fields the data is NULL, which is fine. Could someone tell me what I did wrong here?

I'm using this table:

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

And this insert statement:

$sql = "INSERT INTO tblCustomers (custname,company) 
        VALUES ('".$customerName."','".$_POST["CustomerCompany"]."')";
$res = mysqli_query($mysqli, $sql);

Or using bind variables:

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

回答1:


If you're sure you're not using explicit default values, then check your strict mode:

SELECT @@GLOBAL.sql_mode;
SELECT @@SESSION.sql_mode;

MySQL Data Type Default Values

As of MySQL 5.0.2, if a column definition includes no explicit DEFAULT value, MySQL determines the default value as follows:

If the column can take NULL as a value, the column is defined with an explicit DEFAULT NULL clause. This is the same as before 5.0.2.

If the column cannot take NULL as the value, MySQL defines the column with no explicit DEFAULT clause. For data entry, if an INSERT or REPLACE statement includes no value for the column, or an UPDATE statement sets the column to NULL, MySQL handles the column according to the SQL mode in effect at the time:

  • If strict SQL mode is not enabled, MySQL sets the column to the implicit default value for the column data type.

  • If strict mode is enabled, an error occurs for transactional tables and the statement is rolled back. For nontransactional tables, an error occurs, but if this happens for the second or subsequent row of a multiple-row statement, the preceding rows will have been inserted.

Server SQL Modes




回答2:


What you are doing wrong is building your query using strings instead of using bind parameters.

Aside from the SQL injection vulnerability, the null values are being converted to empty strings even before the database sees them.

$x = null;
print_r("VALUES ('$x', 42)");

Outputs:

VALUES ('', 42)

In other words, you are inserting an empty string, not a NULL. To insert a NULL you would have needed to write this:

VALUES (NULL, 42)

If you use bind parameters then you won't get this problem and as a bonus your site won't have so many security holes. I suggest you read the answer to this question and follow the advice there. This will solve your immediate problem as well as improving the security of your site.




回答3:


I agree with Mark Byers - your php is incorrect for the behavior you want.

Re: Mark's comment on binding parameters, check out PDO in PHP

If you still don't want to use parameters, you could try the following:


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.')';

Edit: Have you considered just checking in your PHP code to ensure the values are not blank/null first? That way you could avoid the trip to the database altogether (based on my interpretation of your comment)? Not really an answer to the MySQL behavior, but might sort out your problem.



来源:https://stackoverflow.com/questions/2503712/mysql-ignores-the-not-null-constraint

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!