Как правильно выполнить повторный запуск подготовленного оператора с использованием разных целых значений?
Там что-то смертельно неправильно с явным и неявным привязкой PDO::PARAM_INT
при повторном использовании подготовленного оператора ODBC.
CREATE TABLE mytab (
col INT,
something VARCHAR(20)
);
Работает: несколько строк
$pdoDB = new PDO('odbc:Driver=ODBC Driver 13 for SQL Server;
Server='.DATABASE_SERVER.';
Database='.DATABASE_NAME,
DATABASE_USERNAME,
DATABASE_PASSWORD
);
$pdoDB->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$values = ['here','are','some','values'];
$sql = "INSERT INTO mytab (something) VALUES (:something)";
$stmt = $pdoDB->prepare($sql);
foreach ($values as $value)
$stmt->execute(['something'=>$value]);
Работы: одиночное целое
$values = [42];
$sql = "INSERT INTO mytab (col) VALUES (:col)";
$stmt = $pdoDB->prepare($sql);
foreach ($values as $value)
$stmt->execute(['col'=>$value]);
Не работает: несколько целых чисел
$values = [1,3,5,7,11];
$sql = "INSERT INTO mytab (col) VALUES (:col)";
$stmt = $pdoDB->prepare($sql);
foreach ($values as $value)
$stmt->execute(['col'=>$value]);
Он фактически успешно вставляет первую запись 1
, но не работает, когда пытается повторить операцию при следующем выполнении.
PHP Неустранимая ошибка: Uncaught PDOException: SQLSTATE [22018]: Недопустимое значение символа для спецификации литья: 206 [Microsoft] [Драйвер ODBC 13 для SQL Server] [SQL Server] Столкновение типа операнда: текст несовместим с int (SQLExecute [ 206] в /build/php 7.0-lPMnpS/php7.0-7.0.8/ext/pdo_odbc/odbc_stmt.c:260)
Я подключаюсь из 64-разрядного Ubuntu 16.04, работающего под управлением PHP 7.0.8, используя Microsoft® ODBC Driver 13 (Preview) для SQL Server®
Я пробовал обернуть все это в PDO::beginTransaction
и PDO::commit
Я также пробовал использовать PDOStatement::bindParam
, но он выдает ту же самую ошибку.
Работы
$values = [1];
$sql = "INSERT INTO mytab (col) VALUES (:col)";
$stmt = $pdoDB->prepare($sql);
foreach ($values as $value){
$stmt->bindParam('col', $value, PDO::PARAM_INT);
$stmt->execute();
}
Не работает
$values = [1,2];
$sql = "INSERT INTO mytab (col) VALUES (:col)";
$stmt = $pdoDB->prepare($sql);
foreach ($values as $value){
$stmt->bindParam('col', $value, PDO::PARAM_INT);
$stmt->execute();
}
Мне кажется интересным отметить, что я получаю ту же ошибку, что и этот вопрос без ответа, используя PHP 5.6.9. Тем не менее, они не могут выполнить хотя бы один оператор, поэтому мне интересно, был ли частичный патч, учитывая, что точная строка, бросающая ошибку, переместилась из odbc_stmt.c:254
до odbc_stmt.c:260
Обход
Если я подготовлю оператор внутри цикла, то он работает нормально. Но я читал, что это очень неэффективно, и я должен иметь возможность повторно использовать инструкцию. Меня особенно беспокоит использование этого с массивными наборами данных. Это нормально? Есть ли что-то лучшее, что я могу сделать?
$values = [1,3,5,7,9,11];
$sql = "INSERT INTO mytab (col) VALUES (:col)";
foreach ($values as $value){
$stmt = $pdoDB->prepare($sql);
$stmt->execute(['col'=>$value]);
}