php - SQLSTATE[HY093]: number of bound variables does not match number of tokens ON DUPLICATE KEY UPDATE with composite KEY
I have read a lot of post with a similar issue and am still stumped..
The table has a composite key idx_aq_contract_estimate (vendorId, projectId).
I have 9 placeholders, 9 values in the $values array, 9 keys in the array_map are mapped to ? for the ON DUPLICATE KEY UPDATE array.
$connection = get_connection();
if(!empty($values) && !empty($table)) {
$columnString = implode(', ', array_keys($values));
$arrayOnDuplicateKeyVal = implode(', ',array_map('getKeyValue',array_keys($values, )));
$valueString = implode(',', array_fill(0, count($values), '?'));
$statement = $connection->prepare("INSERT INTO $table ({$columnString}) VALUES ({$valueString}) ON DUPLICATE KEY UPDATE $arrayOnDuplicateKeyVal");
//print_r ($statement) at this point:
//INSERT INTO `aq_contract_estimate` (vendorId, name, projectId, exportId, total_freight, total_taxable, total_nontaxable, total_credit_taxable, total_credit_nontaxable) VALUES (?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE vendorId = ?, name = ?, projectId = ?, exportId = ?, total_freight = ?, total_taxable = ?, total_nontaxable = ?, total_credit_taxable = ?, total_credit_nontaxable = ?
)
$statement->execute(array_values($values));
print $statement->errorCode();
//prints: Invalid parameter number: number of bound variables does not match number of tokens upon $statement->execute()
print_r($statement->errorInfo());
$statement->closeCursor();
If I remove "ON DUPLICATE KEY UPDATE $arrayOnDuplicateKeyVal")" the statement executes fine, so I am confident my field names are correctly spelled, etc., but I need to handle duplicate keys.
What is incorrect about this approach using tokens vs. named place holders??
Answer
Solution:
You can rewrite your query as
INSERT INTO `aq_contract_estimate` (vendorId, name, projectId, exportId, total_freight, total_taxable, total_nontaxable, total_credit_taxable, total_credit_nontaxable)
VALUES (?,?,?,?,?,?,?,?,?)
ON DUPLICATE KEY UPDATE vendorId = VALUES(vendorId), name = VALUES(name), projectId = VALUES(projectId)
, exportId = VALUES(exportId), total_freight = VALUES(total_freight), total_taxable = VALUES(total_taxable), total_nontaxable = VALUES(total_nontaxable), total_credit_taxable = VALUES(total_credit_taxable )
, total_credit_nontaxable = VALUES(total_credit_nontaxable)
So ar leasr you wouldn't need to double the niber of values.
but ON DUPICATE UPDATE works, when the insert encounters a unique constraint and violates it, so that column or columns you really don't need to update.
Source