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

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

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

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

    Значения по умолчанию для типа данных MySQL

    Начиная с MySQL 5.0.2, если определение столбца не содержит явного значения DEFAULT, MySQL определяет значение по умолчанию следующим образом:

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

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

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

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

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

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

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

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

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