Mysql
儲存過程和準備好的語句
我有 2 個儲存過程:
CREATE PROCEDURE `GetEntryCount`(param_Criteria VARCHAR(500)) BEGIN IF (param_CRITERIA <> "") THEN SET @QUERY1 = concat('SELECT user_name,count(*) as count FROM foodmaster d inner join user_details u on d.user_id=u.user_id WHERE (', param_CRITERIA ,') group by u.user_id;'); PREPARE stmt FROM @QUERY1; EXECUTE stmt; DEALLOCATE PREPARE stmt; END IF; CREATE PROCEDURE `sample`(param_CRITERIA VARCHAR(500)) BEGIN SELECT user_name,count(*) as count FROM foodmaster d inner join user_details u on d.user_id=u.user_id WHERE ( param_CRITERIA ) group by u.user_id; END;
我嘗試在兩個 SP 中使用相同的 param_criteria。在第一個過程中,我得到了結果。但不是第二。為什麼?
因為巧合的是,第二個在語法上是有效的,但不是做你正在做的事情的正確方法。您正在嘗試在不使用動態 sql 的情況下執行動態 sql。您在 #2 中所做的實際上是將文字字元串 ‘, param_CRITERIA ,’ 放在 where 子句中,而不是該變數的內容。
做你想做的事情的唯一方法是方法#1。
我還要指出,如果您在方法 #1 中傳遞的值來自不可信的來源(例如 Web 表單或 url url 查詢字元串),那麼您也可能為 SQL 注入漏洞做好準備。
編輯:
您已經更新了您的問題,因此範例編號 2 不再與我上面的答案一致,因此為了將來清楚起見,我將指出您的原始查詢 #2 如下所示:
... WHERE (,'param_CRITERIA',) group ...
現在您已經刪除了逗號和引號:
... WHERE ( param_CRITERIA ) group ...
這也不起作用,因為正如我所指出的,您正在嘗試將變數的內容插入到查詢的主體中,從而模糊了邏輯和數據之間的界限。做到這一點的唯一方法是製作一個動態 SQL 查詢,這就是您在 #1 中所做的。Example #2 不是一個動態查詢,不能成為一個。