预处理语句不能与整数值被执行多次

问题描述 投票:5回答:1

如何正确地重新执行使用不同的整数值一份声明?

有重新使用ODBC准备语句时的东西死一般的错显性和隐性的结合PDO::PARAM_INT

CREATE TABLE mytab (
    col INT,
    something VARCHAR(20)
);

Works : multiple strings

$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]);

Works : single integer

$values = [42];
$sql = "INSERT INTO mytab (col) VALUES (:col)";
$stmt = $pdoDB->prepare($sql);
foreach ($values as $value)
  $stmt->execute(['col'=>$value]);

Does Not Work : multiple integers

$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致命错误:未捕获PDOException:SQLSTATE [22018]:用于铸铁规范无效字符值:206 [微软] [ODBC SQL Server的驱动程序13] [SQL服务器]操作数类型冲突:文本与诠释不兼容(SQLExecute [206]在/build/php7.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) for SQL Server®连接


我曾尝试在PDO::beginTransactionPDO::commit包裹了整个事情

我已经使用PDOStatement::bindParam也尝试过,但它抛出完全相同的错误。

Works

$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();
}

Does Not Work

$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();
}

我认为这是有趣的是,我收到完全相同的错误,因为这unanswered question使用PHP 5.6.9。然而,它们不能执行甚至一个语句,所以如果有考虑过确切的抛绳该错误的部分区块已经从odbc_stmt.c:254搬到odbc_stmt.c:260我想知道

Workaround

如果我准备循环内的语句,那么它工作得很好。但我读过,这是非常低效的,我应该能够重复使用的语句。我特别担心使用这种具有巨大的数据集。这个可以吗?是否有更好的东西,我可以做什么?

$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]);
}
php sql-server pdo odbc prepared-statement
1个回答
0
投票

在预处理语句的情况下,你必须使用bindParam循环之外,平时。

  1. bindParam是一个单一的步骤
  2. 设置约束变量是可重复的步骤(循环)
  3. 你必须运行execute每个重复

我想,这样的事情会的工作:

$stmt = $pdoDB->prepare("INSERT INTO mytab (col, key) VALUES (:col, :key)");

// bind params (by reference)
$stmt->bindParams(":col", $col, PDO::PARAM_STR); //bind variable $col
$stmt->bindParams(":key", $key, PDO::PARAM_INT); //bind variable $key

$values = ['here','are','some','values'];
foreach ($values as $i => $value) {
    $col = $value; //set col
    $key = $i; //set key
    $stmt->execute();
}
© www.soinside.com 2019 - 2024. All rights reserved.