mysql 存儲過程中使用動態sql語句


Mysql 5.0 以后,支持了動態sql語句,我們可以通過傳遞不同的參數得到我們想要的值

  這里介紹兩種在存儲過程中的動態sql:

  1.  

  set sql = (預處理的sql語句,可以是用concat拼接的語句)

  set @sql = sql

  PREPARE stmt_name FROM @sql;

  EXECUTE stmt_name;

  {DEALLOCATE | DROP} PREPARE stmt_name;

 

復制代碼
CREATE DEFINER = `root`@`%` PROCEDURE `NewProc`(IN `USER_ID` varchar(36),IN `USER_NAME` varchar(36))
BEGIN
    
      declare SQL_FOR_SELECT varchar(500);                                                                                       -- 定義預處理sql語句

      set SQL_FOR_SELECT = CONCAT("select * from  user  where user_id = '",USER_ID,"' and user_name = '",USER_NAME,"'");   -- 拼接查詢sql語句

       set @sql = SQL_FOR_SELECT;
    PREPARE stmt FROM @sql;         -- 預處理動態sql語句
       EXECUTE stmt ;                        -- 執行sql語句
       deallocate prepare stmt;      -- 釋放prepare

END;
復制代碼

 

上述是一個簡單的查詢用戶表的存儲過程,當我們調用此存儲過程,可以根據傳入不同的參數獲得不同的值

   但是:上述存儲過程中,我們必須在拼接sql語句之前把USER_ID,USER_NAME定義好,而且在拼接sql語句之后,我們無法改變USER_ID,USER_NAME的值,如下

復制代碼
 1 CREATE DEFINER = `root`@`%` PROCEDURE `NewProc`(IN `USER_ID` varchar(36),IN `USER_NAME` varchar(36))
 2 BEGIN
 3     
 4         declare SQL_FOR_SELECT varchar(500);                                                                                     -- 定義預處理sql語句
 5 
 6         set SQL_FOR_SELECT = CONCAT("select * from user where user_id = '",USER_ID,"' and user_name = '",USER_NAME,"'");   -- 拼接查詢sql語句
 7 
 8         set @sql = SQL_FOR_SELECT;
 9        PREPARE stmt FROM @sql;        -- 預處理動態sql語句
10        EXECUTE stmt ;                       -- 執行sql語句
11         deallocate prepare stmt;       -- 釋放prepare
12 
13 
14         set USER_ID = '2';
15         set USER_NAME = 'lisi';
16 
17         set @sql = SQL_FOR_SELECT;
18        PREPARE stmt FROM @sql;        -- 預處理動態sql語句
19        EXECUTE stmt ;                       -- 執行sql語句
20         deallocate prepare stmt;      -- 釋放prepare
21 END;
復制代碼

 

   我們用call aa('1','zhangsan');來調用該存儲過程,第一次動態執行,我們得到了‘張三’的信息,然后我們在第14,15行將USER_ID,USER_NAME改為lisi,我們希望得到李四的相關信息,可查出來的結果依舊是張三的信息,說明我們在拼接sql語句后,不能再改變參數了。為了解決這種問題,下面介紹第二中方式

   2.

 set sql = (預處理的sql語句,可以是用concat拼接的語句,參數用 ?代替)

 set @sql = sql

 PREPARE stmt_name FROM @sql;

 set @var_name = xxx;

 EXECUTE stmt_name USING [USING @var_name [, @var_name] ...];

 {DEALLOCATE | DROP} PREPARE stmt_name;

 

上述的代碼我們就可以改成 

復制代碼
 1 CREATE DEFINER = `root`@`%` PROCEDURE `NewProc`(IN `USER_ID` varchar(36),IN `USER_NAME` varchar(36))
 2 BEGIN
 3     
 4         declare SQL_FOR_SELECT varchar(500);                                                                                                                                           -- 定義預處理sql語句
 5 
 6         set SQL_FOR_SELECT = "select * from user where user_id = ? and user_name = ? ";                           -- 拼接查詢sql語句
 7 
 8         set @sql = SQL_FOR_SELECT;
 9         PREPARE stmt FROM @sql;                                                 -- 預處理動態sql語句
10 
11         set @parm1 = USER_ID;                                                      -- 傳遞sql動態參數
12         set @parm2 = USER_NAME;
13 
14         EXECUTE stmt USING @parm1 , @parm2;                          -- 執行sql語句
15         deallocate prepare stmt;                                                -- 釋放prepare
16 
17 
18         set @sql = SQL_FOR_SELECT;
19         PREPARE stmt FROM @sql;                                                 -- 預處理動態sql語句
20 
21         set @parm1 = '2';                                                          -- 傳遞sql動態參數
22         set @parm2 = 'lisi';
23 
24         EXECUTE stmt USING @parm1 , @parm2;                           -- 執行sql語句
25         deallocate prepare stmt;                                                 -- 釋放prepare
26 END;
復制代碼

 

   這樣,我們就可以真正的使用不同的參數(當然也可以在存儲過程中通過邏輯生成不同的參數)來使用動態sql了。

幾個注意:

  •  存儲動態SQL的值的變量不能是自定義變量,必須是用戶變量或者全局變量   如:set sql = 'xxx';  prepare stmt from sql;是錯的,正確為: set @sql = 'xxx';  prepare stmt from @sql;
  •    即使 preparable_stmt 語句中的 ? 所代表的是一個字符串,你也不需要將 ? 用引號包含起來。

  •   如果動態語句中用到了 in 則sql語句應該這樣寫:set @sql = "select * from user where user_id in (?,?,?) "   

 這里我也有個問題,因為有可能我不確定in語句里有幾個參數,所以我試過這么寫

  set @sql = "select * from user where user_id in (?) "  

然后參數我傳的是  "'1','2','3'"  我以為程序會將我的動態sql解析出來(select * from user where user_id in ('1','2','3')) 但是並沒有解析出來,各位大俠們幫幫忙,有什么好方法解決這個問題么?

 

 

轉載至:https://www.cnblogs.com/fenxiangheiye/archive/2013/02/18/Mysql.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM