MySQL预准备语句报错:未为参数提供数据的问题排查
Ah, I see the issue here! The error is happening because your prepared statement has 8 placeholders total, but you're only binding 4 values. Let me break it down:
Your INSERT clause has 4 ? placeholders for the VALUES, and then your ON DUPLICATE KEY UPDATE clause adds another 4 ? placeholders (one for each column you're updating). That means MySQL is expecting 8 values to be bound, but your bind_param call only provides 4. That's why you get the "No data supplied for parameters" error.
There are two ways to fix this:
1. Bind all 8 parameters (the redundant way)
You could repeat the same variables in your bind_param call to cover all 8 placeholders. Your SQL stays the same, but you'd update the bind line to:
$stmt1->bind_param("ssssssss", $row['DSLAM'], $row['SHELF_PT_NUMBER'], $row['CARD_PT_NUMBER'], $row['CARD_PT_DESCRIPTION'], $row['DSLAM'], $row['SHELF_PT_NUMBER'], $row['CARD_PT_NUMBER'], $row['CARD_PT_DESCRIPTION'] );
Note the ssssssss type string (8 s characters, matching the 8 parameters) and repeating each variable twice. But this is unnecessary repetition—let's use a better approach.
2. Use VALUES(column) to reuse insert values (cleaner solution)
MySQL lets you reference the value that would have been inserted for a column using VALUES(column) in the UPDATE clause. This way, you don't need to bind the same variables twice. Modify your SQL statement to:
$stmt1 = $mysqli1->prepare(" INSERT INTO na_dslam_card (n_alias, shelf_pt_num, card_pt_num, card_pt_description) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE n_alias = VALUES(n_alias), shelf_pt_num = VALUES(shelf_pt_num), card_pt_num = VALUES(card_pt_num), card_pt_description = VALUES(card_pt_description) ");
Now your prepared statement only has 4 placeholders, so your original bind_param("ssss", ...) line will work perfectly—no changes needed there!
One more critical check: Ensure your table has a unique key
For ON DUPLICATE KEY UPDATE to work at all, your table must have a primary key or unique constraint on the column(s) that define a duplicate row. Looking at your table structure, you have an index field—if that's the primary key but you're not inserting into it, duplicates won't be detected.
You need to define which column(s) make a row unique. For example, if n_alias should be unique, run this SQL to add the constraint:
ALTER TABLE na_dslam_card ADD UNIQUE KEY (n_alias);
Or if it's a combination of columns:
ALTER TABLE na_dslam_card ADD UNIQUE KEY (n_alias, shelf_pt_num, card_pt_num);
Without this unique key, the ON DUPLICATE KEY UPDATE will never trigger—it'll just insert new rows every time, even if you fix the parameter binding.
Handling NULL values
Since you mentioned some fields might be NULL, don't worry—MySQL will handle NULL values correctly here. The s type in bind_param works for NULL strings, converting them to MySQL NULL values, and your Oracle query is already returning NULLs for missing fields thanks to OCI_RETURN_NULLS.
内容的提问来源于stack exchange,提问作者Michele

