MySQL игнорирует ограничение NOT NULL

Я создал таблицу с NOT NULL ограничения на некоторые столбцы в MySQL. Затем в PHP я написал скрипт для вставки данных с запросом insert. Когда я опускаю один из NOT NULL столбцы в этой инструкции insert я ожидал бы сообщение об ошибке от 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);

или использование переменных bind:

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

3 ответов


Если вы уверены, что не используете явные значения по умолчанию, проверьте строгий режим:

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

MySQL Тип Данных Значения По Умолчанию

начиная с MySQL 5.0.2, если столбец определение не содержит явных Значение по умолчанию, MySQL определяет значение по умолчанию:

Если столбец может принимать значение NULL как значение, столбец определяется с помощью явное предложение null по умолчанию. Это то же, что и до 5.0.2.

Если столбец не может принимать значение NULL в качестве значение, MySQL определяет столбец с нет явного предложения по умолчанию. Для данных запись, если вставить или заменить инструкция не содержит значения для столбец или наборы инструкций UPDATE столбец в NULL, MySQL обрабатывает столбец в соответствии с режимом SQL в эффект в то время:

  • Если строгий режим SQL не включен, MySQL устанавливает столбец в неявное значение по умолчанию для столбца данные тип.

  • если включен строгий режим, возникает ошибка для таблиц транзакций и заявление откатывается. Для нетранзакционные таблицы, ошибка происходит, но если это происходит на вторая или последующая строка оператор multiple-row, предыдущий строки будут вставлены.

режимы SQL сервера


то, что вы делаете неправильно, - это построение запроса с использованием строк вместо использования параметров привязки.

помимо уязвимости SQL-инъекции, значения null преобразуются в пустые строки еще до того, как база данных их увидит.

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

выходы:

VALUES ('', 42)

другими словами, вы вставляете пустую строку, а не NULL. Чтобы вставить NULL, вам нужно было бы написать следующее:

VALUES (NULL, 42)

Если вы используете параметры привязки, то вы не получите эту проблему и в качестве бонуса ваш сайт не будет иметь столько дыр в безопасности. Я предлагаю вам прочитать ответ этот вопрос и следуйте советам там. Это решит вашу непосредственную проблему, а также улучшит безопасность вашего сайта.


Я согласен с Марком Байерсом - ваш php неверен для поведения, которое вы хотите.

Re: комментарий Марка к параметрам привязки, проверьте PDO в 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.')';

Edit: вы рассматривали просто проверку вашего PHP-кода, чтобы убедиться, что значения не пустые/нулевые? Таким образом, вы можете избежать поездки в базу данных вообще (на основе моего интерпретация вашего комментария)? Не совсем ответ на поведение MySQL, но может решить вашу проблему.