儲存過程參數名若與表欄位名相同,參數值會被欄位值覆蓋,導致邏輯錯誤甚至誤刪全表資料。
CREATE PROCEDURE sp_delete_species(
IN species_id INT, -- 參數名 = 欄位名
OUT out_rows INT
)
BEGIN
DELETE FROM `sample` WHERE `species_ID` = species_id; -- species_id 解析為欄位,非參數!
DELETE FROM `filepath` WHERE `species_ID` = species_id;
DELETE FROM `species` WHERE `species_ID` = species_id;
SET out_rows = ROW_COUNT();
END;
結果:species_id 在 WHERE 中被解析為表欄位,條件恆為真(欄位=自身),導致三表全表刪除。
CREATE PROCEDURE sp_delete_species(
IN p_species_id INT, -- 參數前綴 p_
OUT p_out_rows INT
)
BEGIN
DELETE FROM `sample` WHERE `species_ID` = p_species_id;
DELETE FROM `filepath` WHERE `species_ID` = p_species_id;
DELETE FROM `species` WHERE `species_ID` = p_species_id;
SET p_out_rows = ROW_COUNT();
END;
| 物件 | 前綴 | 範例 |
|---|---|---|
| 輸入參數 | p_ | p_user_id, p_start_date |
| 輸出參數 | o_ / p_out_ | o_total_count |
| 輸入輸出參數 | pio_ | pio_status |
| 區域變數 | v_ | v_row_count, v_flag |
| 游標 | cur_ | cur_user_list |
| 條件處理器 | h_ | h_not_found |
雖然參數優先級理論高於欄位,但在某些上下文(如 WHERE 子句未限定表別名)會產生歧義,強制加前綴是唯一保險做法。
pt-query-digest --review 可掃描出潛在命名衝突