mysql存储过程中用变量做表名
mysql存储过程中用变量做表名
1.用变量做表名:
简单的用set或者declare语句定义变量,然后直接作为sql的表名是不行的,mysql会把变量名当作表名。在其他的sql数据库中也是如此,mssql的解决方法是将整条sql语句作为变量,其中穿插变量作为表名,然后用sp_executesql调用该语句。
这在mysql5.0之前是不行的,5.0之后引入了一个全新的语句,可以达到类似sp_executesql的功能(仅对procedure有效,function不支持动态查询):
PREPARE stmt_name FROM preparable_stmt; EXECUTE stmt_name [USING @var_name [, @var_name] ...]; {DEALLOCATE | DROP} PREPARE stmt_name;
mysql> PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; mysql> SET @a = 3; mysql> SET @b = 4; mysql> EXECUTE stmt1 USING @a, @b; +------------+ | hypotenuse | +------------+ | 5 | +------------+ mysql> DEALLOCATE PREPARE stmt1; mysql> SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; mysql> PREPARE stmt2 FROM @s; mysql> SET @a = 6; mysql> SET @b = 8; mysql> EXECUTE stmt2 USING @a, @b; +------------+ | hypotenuse | +------------+ | 10 | +------------+ mysql> DEALLOCATE PREPARE stmt2;
mysql> SET @a=1;mysql> PREPARE STMT FROM "SELECT * FROM tbl LIMIT ?"; mysql> EXECUTE STMT USING @a; mysql> SET @skip=1; SET @numrows=5; mysql> PREPARE STMT FROM "SELECT * FROM tbl LIMIT ?, ?"; mysql> EXECUTE STMT USING @skip, @numrows;
CREATE PROCEDURE `p1`(IN id INT UNSIGNED,IN name VARCHAR(11)) BEGIN lable_exit: BEGIN SET @SqlCmd = 'SELECT * FROM tA '; IF id IS NOT NULL THEN SET @SqlCmd = CONCAT(@SqlCmd , 'WHERE id=?'); PREPARE stmt FROM @SqlCmd; SET @a = id; EXECUTE stmt USING @a; LEAVE lable_exit; END IF; IF name IS NOT NULL THEN SET @SqlCmd = CONCAT(@SqlCmd , 'WHERE name LIKE ?'); PREPARE stmt FROM @SqlCmd; SET @a = CONCAT(name, '%'); EXECUTE stmt USING @a; LEAVE lable_exit; END IF; END lable_exit; END; CALL `p1`(1,NULL); CALL `p1`(NULL,'QQ'); DROP PROCEDURE `p1`;