MySQL 帶參數(shù)的存儲(chǔ)過(guò)程(動(dòng)態(tài)執(zhí)行SQL語(yǔ)句)

MySQL5.0 以后,支持動(dòng)態(tài)sql語(yǔ)句。
當(dāng)SQL語(yǔ)句中 字段名,表名,數(shù)據(jù)庫(kù)名等 要作為變量時(shí),必須要使用動(dòng)態(tài)SQL。
MySQL動(dòng)態(tài)SQL語(yǔ)法如下:

set sql = (預(yù)處理的sql語(yǔ)句,可以是用concat拼接的語(yǔ)句)
set @sql = sql //你的sql語(yǔ)句
PREPARE stmt FROM @sql; 
EXECUTE stmt (如果sql有參數(shù)的話, USING xxx,xxx); // 這里USING的只能是會(huì)話變量;
DEALLOCATE PREPARE stmt;

1、 定義要執(zhí)行的sql變量,并為其賦值
2、預(yù)定義好要使用的sql.
3、執(zhí)行預(yù)定義的sql
4、釋放掉數(shù)據(jù)庫(kù)連接

實(shí)例1:

delimiter //
create procedure pro_test()
begin
set @_sql = 'select ? + ?';
set @a = 5;
set @b = 6;
PREPARE stmt from @_sql; // 預(yù)定義sql
EXECUTE stmt USING @a,@b;// 傳入兩個(gè)會(huì)話變量來(lái)填充sql中的 ?
DEALLOCATE PREPARE stmt; // 釋放連接
end //

調(diào)用:
call pro_test();
返回結(jié)果:11

實(shí)例2:

delimiter //
CREATE PROCEDURE pro_stu(in order_param VARCHAR(50),in startindex int ,in size int)
BEGIN
     set @v_sql = "select * from student s ORDER BY ?  LIMIT ?,?";
     PREPARE stmt from @v_sql;
      set @a = order_param;
      set @b = startindex;
      set @c = size;
      
      EXECUTE stmt using @a,@b,@c;
      DEALLOCATE PREPARE stmt;
end//
delimiter;

調(diào)用:
call pro_stu('s.s_no desc',0,20);
輸出結(jié)果:


image.png

注意:MySQL 在存儲(chǔ)過(guò)程中是不支持直接使用變量名作為表名或者是列名的,而在實(shí)際的應(yīng)用中確實(shí)會(huì)用到變表名或者變量名的情況。以下實(shí)例簡(jiǎn)單說(shuō)明動(dòng)態(tài)表名、列名的查詢。

實(shí)例3:

DROP PROCEDURE IF EXISTS select_test;

delimiter //
create PROCEDURE select_test(tableName varchar(20)) 
-- 創(chuàng)建存儲(chǔ)過(guò)程 命名為tests

BEGIN   -- 存儲(chǔ)過(guò)程的開(kāi)始
  set @tableNames = CONCAT(tableName); -- @先在用戶變量中保存值然后在以后引用它
  set @v_sql = CONCAT('select * from ',@tableNames);-- 拼接查詢總記錄的SQL語(yǔ)句 
  prepare stmt from @v_sql; -- 預(yù)定義一個(gè)語(yǔ)句,并將它賦給 stmt
  execute stmt ; -- 執(zhí)行語(yǔ)句
  deallocate prepare stmt;-- 要釋放一個(gè)預(yù)定義語(yǔ)句的資源
end//-- 存儲(chǔ)過(guò)程的結(jié)束
delimiter;

調(diào)用:
call select_test('student');

實(shí)例4:

DROP PROCEDURE IF EXISTS myTest1;

delimiter //
create procedure myTest1(in columnName varchar(50)) -- 傳入一個(gè)字符串
BEGIN
drop table if exists tmpTable; -- 如果臨時(shí)表存在先刪除掉
set @_sql = concat('create temporary table if not exists tmpTable( ', columnName, ' varchar(50), id int(15), name varchar(50));'); -- 創(chuàng)建臨時(shí)表的語(yǔ)法,我們把傳入的參數(shù)拼接進(jìn)來(lái)
PREPARE stmt from @_sql;    
EXECUTE stmt;
DEALLOCATE PREPARE stmt;  -- 執(zhí)行
desc tmpTable;
end //

調(diào)用:
call myTest1('password');
輸出結(jié)果:


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容