Пустая строка в ненулевом столбце в MySQL?

Раньше я использовал стандартные операторы mysql_connect (), mysql_query () и т. д. Для работы с MySQL из PHP. В последнее время я перехожу на использование замечательного класса MDB2. Наряду с этим я использую подготовленные операторы, поэтому мне не нужно беспокоиться о том, чтобы избежать атак ввода и SQL-инъекций.

Однако есть одна проблема, с которой я сталкиваюсь. У меня есть таблица с несколькими столбцами VARCHAR, которые указаны как ненулевые (то есть не допускают значений NULL). Используя старые команды MySQL PHP, я мог без проблем делать такие вещи:

INSERT INTO mytable SET somevarchar = '';

Однако теперь, если у меня есть такой запрос:

INSERT INTO mytable SET somevarchar = ?;

А затем в PHP у меня есть:

$value = "";
$prepared = $db->prepare($query, array('text'));
$result = $prepared->execute($value);

Это вызовет ошибку "null value violates not-null constraint".

В качестве временного обходного пути я проверяю, пуст ли $value, и меняю его на " " (один пробел), но это ужасный взлом и может вызвать другие проблемы.

Как я должен вставлять пустые строки с подготовленными операторами, не пытаясь вместо этого вставить NULL?

Обновлено: Это слишком большой проект, чтобы просмотреть всю мою кодовую базу, найти везде, где используется пустая строка "", и изменить ее, чтобы вместо этого использовать NULL. Мне нужно знать, почему стандартные запросы MySQL рассматривают "" и NULL как две отдельные вещи (как я считаю правильным), а подготовленные операторы преобразуют "" в NULL.

Обратите внимание, что "" и NULL - это нет одно и то же. Например, SELECT NULL = ""; возвращает NULL вместо 1, как и следовало ожидать.

Если вы вставляете "", который в основном имеет значение null, почему бы не изменить поле в базе данных, чтобы разрешить null.

UnkwnTech 05.11.2008 23:09

он "в основном" равен нулю, так же как 0 является "в основном" ложным. они похожи, но на самом деле совсем разные.

nickf 05.11.2008 23:11

NULL означает «нет значения», а не «пустая строка»

warren 05.11.2008 23:12

Потому что у меня есть код, который выглядит так: SELECT FROM table WHERE column = "", а "" не равно NULL.

davr 05.11.2008 23:14

Это правда, но хранение «пустого» в том смысле, что оно не содержит данных, значения, почти положительное, стоит дороже, чем хранение NULL.

UnkwnTech 05.11.2008 23:14

Вы правы, что NULL - это не то же самое, что "", но вы не должны проводить сравнение, например, SELECT NULL = ""; они всегда будут возвращать null независимо от того, какое значение вы сравниваете с null

Tom Haigh 06.11.2008 01:25
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
13
6
38 181
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Разве это не пустой набор кавычек, ""?

Нет, "" и NULL - разные вещи и ведут себя по-разному в большинстве баз данных.

davr 05.11.2008 23:35

@davr - именно поэтому я сказал это сделать - он пытается получить значение NOT NULL в базу данных, а пустые кавычки

warren 05.11.2008 23:49

Я запутался. Похоже, вы используете mysqli OO (из тегов и стиля), но синтаксис отличается от руководство по эксплуатации на php.net, в котором вместо этого говорится:

$query = "INSERT INTO mytable SET somevarchar = ?";
$value = "";
$prepared = $db->prepare($query);
$prepared->bind_param("s", $value);
$result = $prepared->execute();

Я использую MDB2, который внутренне использует mysqli.

davr 05.11.2008 23:35
Ответ принят как подходящий

Это похоже на проблему с API MDB2, который неуклюже искажает семантику PHP-типа "утка". Поскольку пустая строка в PHP эквивалентна NULL, MDB2, вероятно, неправильно интерпретирует ее как таковую. Идеальным решением было бы найти обходной путь в своем API, но я не слишком хорошо с ним знаком.

Однако следует учитывать одну вещь: пустая строка в SQL не является значением NULL. Вы можете просто вставить их в строки, объявленные NOT NULL:

mysql> CREATE TABLE tbl( row CHAR(128) NOT NULL );
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO tbl VALUES( 'not empty' ), ( '' );
Query OK, 2 rows affected (0.02 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT row, row IS NULL FROM tbl;
+-----------+-------------+
| row       | row IS NULL |
+-----------+-------------+
| not empty |           0 | 
|           |           0 | 
+-----------+-------------+
2 rows in set (0.00 sec)

mysql> INSERT INTO tbl VALUES( NULL );
ERROR 1048 (23000): Column 'row' cannot be null

Если вы не можете найти (или реализовать) обходной путь в MDB2 API, одно из хакерских решений (хотя и немного лучше, чем то, которое вы сейчас используете) может заключаться в определении переменная пользователя для пустой строки -

SET @EMPTY_STRING = "";
UPDATE tbl SET row=@EMPTY_STRING;

Наконец, если вам нужно использовать пустую строку в операторе INSERT, но вы не можете этого сделать, значение по умолчанию для строковых типов в MySQL - это пустая строка. Таким образом, вы можете просто опустить столбец из оператора INSERT, и он автоматически установит пустую строку (при условии, что столбец имеет ограничение NOT NULL).

Вот и все, я не думал, что виноват сам MDB2. Спасибо.

davr 05.11.2008 23:34

Благодаря некоторым ответам я понял, что проблема может быть в API MDB2, а не в самих командах PHP или MYSQL. Конечно же, я нашел это в FAQ по MDB2:

  • Why do empty strings end up as NULL in the database? Why do I get an NULL not allowed in NOT NULL text fields eventhough the default value is ""?
    • The problem is that for some RDBMS (most noteably Oracle) an empty string is NULL. Therefore MDB2 provides a portability option to enforce the same behaviour on all RDBMS.
    • Since all portability options are enabled by default you will have to disable the feature if you dont want to have this behaviour: $mdb2->setOption('portability', MDB2_PORTABILITY_ALL ^ MDB2_PORTABILITY_EMPTY_TO_NULL);

Спасибо всем, кто дал обстоятельные ответы.

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

Не зная, к чему относится столбец NULL / "", я не могу понять истинное значение пустой строки. Означает ли пустая строка что-то само по себе (например, если бы я убедил судью позволить мне изменить мое имя на просто ничто, я был бы очень раздражен, если бы мое имя появилось в моих водительских правах как NULL. Моё имя было бы!

Однако пустая строка (или пробел, или ничто, являющееся ЧТО-ТО, а не просто отсутствие чего-либо (например, NULL)) также может просто означать «NOT NULL» или «Nothing, но все же не NULL». Вы даже можете пойти в другом направлении и предположить, что отсутствие значения NULL делает его даже МЕНЬШЕ чем-то, чем Null, потому что, по крайней мере, у Null есть имя, которое вы можете произнести вслух!

Я хочу сказать, что если пустая строка является прямым представлением некоторых данных (например, имени или того, что я предпочитаю вставлять между числами в моем номере телефона и т. д.), Тогда вы можете спорить, пока не почувствуете боль. для законного использования пустой строки или для использования чего-то, что представляет собой пустую строку, которая не является NULL (например, управляющий символ ASCII или некоторый эквивалент Unicode, какое-либо значение регулярного выражения или, что еще хуже, произвольный, но полностью неиспользуемый токен , например: ◘

Если пустая ячейка на самом деле означает НЕ NULL, вы можете придумать другой способ выразить это. Один глупый и очевидный способ - это фраза «Not NULL». Но у меня есть подозрение, что NULL означает что-то вроде «Не входит в эту группу вообще», а пустая строка означает что-то вроде «этот парень крутой, просто у него еще нет татуировок банды». В этом случае я бы предложил термин / название / идею для этой ситуации, например «по умолчанию», «новичок» или «ожидает рассмотрения».

Теперь, если по какой-то безумной случайности вы действительно хотите, чтобы пустая строка представляла то, что даже не достойно NULL, снова придумайте для этого более значимый символ, такой как «-1», «SUPERNULL» или «UGLIES».

В индийской кастовой системе низшая каста - это шудра: фермеры и рабочие. Под этой кастой находятся далиты: «Неприкасаемые». Они не считаются низшей кастой, потому что установка их как низшей касты будет считаться заражением всей системы.

Так что не называйте меня сумасшедшим из-за того, что я считаю, что пустые строки могут быть ХУЖЕ, чем NULL!

До следующего раза.

Я нашел решение!

MDB2 преобразует пустые строки в NULL, потому что опция переносимости MDB2_PORTABILITY_EMPTY_TO_NULL включена по умолчанию (благодаря Oracle, который считает пустые строки нулевыми).

Отключите эти параметры при подключении к базе данных:

$options = array(
    'portability' => MDB2_PORTABILITY_ALL ^ MDB2_PORTABILITY_EMPTY_TO_NULL
);
$res= & MDB2::connect("mysql://user:password@server/dbase", $options);

ммм ... Я написал этот точный ответ больше года назад.

davr 19.02.2010 20:09

В то время как 0 и пустые строки являются переменными, NULL означает отсутствие данных. И поверьте мне, намного проще написать запрос к

SELECT * from table where mything IS NULL, чем пытаться запросить пустые строки: /

Другие вопросы по теме