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

Я составил таблицу с NOT NULL ограничения на некоторые столбцы в MySQL. Затем в PHP я записал сценарий для вставки данных с запросом на вставку. Когда я опускаю один из NOT NULL столбцы в этом операторе вставки, я ожидал бы сообщение об ошибке от MySQL, и я буду ожидать, что мой сценарий перестанет работать. Вместо этого MySQL вставляет пустые строки в NOT 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);
10
задан Whakkee 23 March 2010 в 22:36
поделиться

3 ответа

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

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

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

Как MySQL 5.0.2, если определение столбца не включает явного значения ПО УМОЛЧАНИЮ, MySQL определяет значение по умолчанию следующим образом:

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

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

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

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

Серверные режимы SQL

16
ответ дан 3 December 2019 в 17:58
поделиться

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

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

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

Вывод:

VALUES ('', 42)

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

VALUES (NULL, 42)

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

5
ответ дан 3 December 2019 в 17:58
поделиться

Я согласен с Марком Байерсом - ваш 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-код, чтобы сначала убедиться, что значения не пустые / нулевые? Таким образом, вы могли бы вообще избежать посещения базы данных (исходя из моей интерпретации вашего комментария)? Не совсем ответ на поведение MySQL, но может решить вашу проблему.

1
ответ дан 3 December 2019 в 17:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: