MySQL INSERT вставляя бит в 1 вместо 0

0

У меня есть следующий запрос, который должен вставить 0, но вместо этого вставляет 1. Он выполняется с подготовленными операторами в PHP:

$insertsql= 
    "INSERT INTO table1 (column1, column2, column3, column4, column5, column6) 
    VALUES (?, ?, ?, ?, ?, ?)";
$insertstmt = $pdo->prepare($insertsql);
$insertstmt->execute(array($var1, $var2, $var3, $var4, $var5, 0));

Все вставки выполняются нормально, за исключением того, что 1 вставляется в столбец 6 вместо 0. Столбец 6 имеет тип данных BIT.

Запрос работает нормально, однако при выполнении

INSERT INTO table1 (column6) VALUE (0);

прямо во вкладке phpmyadmin 'MySQL'.

Что мне не хватает?

РЕДАКТИРОВАТЬ: Использование

$insertstmt->execute(array($var1, $var2, $var3, $var4, $var5, false));

работает как положено. Почему 0 работает непосредственно в запросе SQL, а не при использовании pdo для его выполнения?

  • 5
    Тип привязки по умолчанию при передаче таких привязок - строка, что означает, что 0 станет '0' а если это затем каким-либо образом приведено к логическому bindValue оно станет 1. Я предлагаю вам использовать bindValue со вторым параметром, чтобы явно указать, какие типы вы используете. обязательна.
Теги:
pdo

1 ответ

2
Лучший ответ

Вы должны явно объявить этот параметр как Boolean при передаче его в PDO.

Из ПДО execute документацию:

input_parameters

Массив значений с таким количеством элементов, сколько связанных параметров в выполняемой инструкции SQL. Все значения рассматриваются как PDO::PARAM_STR.

Это не то, что вы хотите.

Поэтому вам нужно будет изменить логику, чтобы избежать использования конструкции execute(array()) и привязывать каждый параметр отдельно, используя bindValue(). Для логического:

$insertstmt->bindValue(':col6', false, PDO::PARAM_BOOL);

Поскольку логические значения в MySQL просто TINYINT(1), PDO::PARAM_INT должен работать нормально:

$insertstmt->bindValue(':col6', 0, PDO::PARAM_INT);

И наконец: если это логическое значение всегда будет ложным, вы можете передать его непосредственно в запрос, например:

$insertstmt->execute(array($var1, $var2, $var3, $var4, $var5, false));

Как мудро прокомментировал spencer7593, другой вариант - это приведение типов из SQL. Например, можно преобразовать строку в битовое значение с помощью:

INSERT INTO table1 (column1, column2, column3, column4, column5, column6) 
VALUES (?, ?, ?, ?, ?, IF( ? ='0', b'0', b'1') )
  • 0
    Стоит также отметить, что если значение на самом деле жестко запрограммировано, нет необходимости использовать для него параметр, поскольку параметры главным образом предназначены для очистки входных данных, поступающих из ненадежных источников.
  • 0
    @apokryfos: параметры также позволяют RDBM оптимизировать выполнение запроса путем пропуска анализа и подготовки плана выполнения. Без параметров связывания СУБД обычно не может распознать, что вы выполняете один и тот же запрос снова и снова.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню