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