准备多重插入查询时出错

2022-08-30 11:41:45
// BUILD VALUES
$count = count($matches);
for($i = 0; $i < $count; ++$i) {
    $values[] = '(?)';
}
// INSERT INTO DATABASE
$q = $this->dbc->prepare("INSERT INTO hashes (hash) VALUES " . implode(', ', $values) . " ON DUPLICATE KEY UPDATE hash = hash");
$q->execute($matches);

上面的代码失败,并出现以下错误

SQLSTATE[HY093]: 参数编号无效: 参数未定义

虽然当执行之前被调用?count($matches) == count($values)

这是怎么回事?


答案 1

您收到的此错误是因为 & 中的元素数量不匹配。$values$matches

如果 & 不包含相同数量的元素,则插入将失败,因为查询需要 X 参数,但它正在接收 Y 数据。在您的情况下,可能已经包含一些值,这就是计数不匹配的原因。为避免这种情况,必须始终在循环之前初始化数组。$values$matches$matches$values

我相信您还需要确保列哈希也有唯一的索引。

$matches = array('1');
$count = count($matches);
$values = [];
for($i = 0; $i < $count; ++$i) {
    $values[] = '(?)';
}

// INSERT INTO DATABASE
$sql = "INSERT INTO hashes (hash) VALUES " . implode(', ', $values) . " ON DUPLICATE KEY UPDATE hash=values(hash)";
$stmt = $dbh->prepare($sql);
$data = $stmt->execute($matches);

答案 2

SQLSTATE[HY093]: 参数编号无效: 参数未定义

遗憾的是,此错误不能描述与同一问题相关的一系列不同问题 - 绑定错误。它也没有指定错误的位置,因此您的问题不一定在执行中,而是已经“准备好”的sql语句。

以下是可能的错误及其解决方案:

  1. 存在参数不匹配 - 字段数与已绑定的参数不匹配。注意数组中的数组。要仔细检查,请使用var_dump($var)。。“print_r”不一定显示数组中的索引是否为另一个数组(如果数组中有一个值),而var_dump将。

  2. 您尝试使用相同的绑定值进行绑定,例如:“:hash”和“:hash”。每个索引都必须是唯一的,即使从逻辑上讲,对两个不同的部分使用相同的索引是有意义的,即使它的值相同。(它类似于常量,但更像是占位符)

  3. 如果要在语句中绑定多个值(通常使用“INSERT”),则需要绑定参数,然后将 bindValue 绑定到参数。此处的过程是将参数绑定到字段,然后将值绑定到参数。

     // Code snippet
     $column_names = array();
     $stmt->bindParam(':'.$i, $column_names[$i], $param_type);
     $stmt->bindValue(':'.$i, $values[$i], $param_type);
     $i++;
     //.....
    
  4. 当您使用反引号分隔表示标识符(而不是字符串)的文本时不一致。(使用''),但是一旦你使用它们,你必须对该查询保持一致,即你不能对一个标识符使用反引号而不对另一个标识符使用它们,如果你使用它们,所有这些都必须有反引号。(例如,从中选择 )不要对占位符使用回勾符idmy_table

  5. '' 单引号中的任何值始终被视为字符串文本,不会作为要绑定到的列/表名称或占位符读取。


推荐