Reputation: 19425
When I run the following code:
// Loop through each store and update shopping mall ID
protected function associateShmallToStore($stores, $shmall_id) {
foreach($stores as $store_id) {
$sql .= 'UPDATE my_table SET fk_shmallID = :shmall_id WHERE id = :store_id';
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':shmall_id', $shmall_id);
$stmt->bindParam(':store_id', $store_id);
$stmt->execute();
}
}
I get the following message:
Warning: PDOStatement::execute() [pdostatement.execute]: SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters
I've also tried the following without success (without $stmt->bindParam
):
$stmt->execute( array($shmall_id, $store_id));
I don't understand what I'm doing wrong.
UPDATE I've updated my code to reflect what I actually got in my source code. There should not be any typos here.
UPDATE 2
I tried this, but I still get the same error message.
protected function associateShmallToStore($stores, $shmall_id) {
$i = 0;
$sql .= "UPDATE sl_store ";
foreach($stores as $store_id) {
$i++;
$sql .= 'SET fk_shmallID = :shmall_id, lastUpdated = NOW() WHERE id = :store_id_'.$i.',';
}
$sql = removeLastChar($sql);
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':shmall_id_'.$i, $shmall_id);
$i = 0;
foreach($stores as $store_id) {
$i++;
$stmt->bindParam(':store_id_'.$i, $store_id);
}
$stmt->execute();
}
This is the output of the SQL query:
UPDATE sl_store
SET fk_shmallID = :shmall_id, lastUpdated = NOW() WHERE id = :store_id_1,
SET fk_shmallID = :shmall_id, lastUpdated = NOW() WHERE id = :store_id_2
UPDATE 3
The code I endet up using was this:
foreach($stores as $store_id) {
$sql = "UPDATE sl_store SET fk_shmallID = :shmall_id WHERE id = :store_id";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':shmall_id', $shmall_id);
$stmt->bindParam(':store_id', $store_id);
$res = $stmt->execute();
}
Upvotes: 0
Views: 616
Reputation: 63452
It's just as the error says, you have mixed named and positional parameters:
:name
(named):person_id
(named)?
(positional)More than that, you have the named parameter :person_id
, but you're binding to :id
.
These are your parameters, I'll call them P1
, P2
and P3
:
UPDATE my_table SET name = :name WHERE id = :person_id ?
^ P1 ^ P2 ^ P3
And this is where you bind them:
$stmt->bindParam(':name', $name); // bound to P1 (:name)
$stmt->bindParam(':id', $person_id); // bound to nothing (no such param :id)
You probably want to bind the second parameter to :person_id
, not to :id
, and remove the last positional parameter (the question mark at the end of the query).
Also, each iteration through the foreach
loop appends more to the query, because you're using the concatenation operator instead of the assignment operator:
$sql .= 'UPDATE my_table SET name = :name WHERE id = :person_id ?';
You probably want to remove that .
before =
.
For more about this, take a look at the Prepared statements and stored procedures page in the PDO manual. You will find out how to bind parameters and what the difference is between named and positional parameters.
So, to sum it up:
Replace the SQL line with:
$sql = 'UPDATE my_table SET name = :name WHERE id = :person_id';
Replace the second bindParam()
call with:
$stmt->bindParam(':person_id', $person_id);
Upvotes: 4