2012-04-13 81 views
2

我正在尝试编写一个存储过程来包装SHOW CREATE TABLE。我的最终目标是动态查找information_schema中的模式名称并运行SHOW CREATE TABLE schema.tableName。mysql存储过程执行SHOW CREATE TABLE

看来我不能在存储过程中运行SHOW CREATE TABLE。

DELIMITER $$ 
DROP PROCEDURE IF EXISTS ct$$ 
CREATE PROCEDURE ct (tableName VARCHAR(50)) 
BEGIN 

    SHOW CREATE TABLE tableName; 

END$$ 
DELIMITER ; 


mysql> CALL ct('users'); 
ERROR 1146 (42S02): Table 'adcentraldb.tableName' doesn't exist 
mysql> 

对于那些有兴趣这就是我最终的SHOW创建一个工作

DELIMITER $$ 
DROP PROCEDURE IF EXISTS ct$$ 

-- Wraps around SHOW CREATE TABLE. Look at other schemas other than current. 
CREATE PROCEDURE ct (tableName VARCHAR(50)) 
BEGIN 
    DECLARE dbName VARCHAR(50); 

    SET dbName = (SELECT `TABLE_SCHEMA` FROM `INFORMATION_SCHEMA`.`TABLES` 
    WHERE `TABLE_NAME` = tableName LIMIT 1); 

    SET @a=CONCAT("SHOW CREATE TABLE ", dbName, '.', tableName); 
    PREPARE stmt1 FROM @a; 
    EXECUTE stmt1; 
    DEALLOCATE PREPARE stmt1; 

END$$ 
DELIMITER ; 
+0

无法将数据库或表名称作为参数传递给MySQL存储过程。相反,您需要构建一个SQL字符串和'EXECUTE()'它,这意味着您还必须谨慎对待SQL注入。 – 2012-04-13 01:20:36

+0

查看[这个问题](http://stackoverflow.com/questions/9993908/passing-fieldname-as-parameter-in-mysql-stored-procedure) – 2012-04-13 01:22:10

+0

@Yada我的答案是否适合你? – 2012-04-13 12:13:18

回答

2

你不可错过的表名这样的表的包装,但你可以为此目的使用准备语句 -

DELIMITER $$ 
DROP PROCEDURE IF EXISTS ct$$ 
CREATE PROCEDURE ct (tableName VARCHAR(50)) 
BEGIN 

    set @a=concat("SHOW CREATE TABLE ",tableName); 
    PREPARE stmt1 FROM @a; 
    EXECUTE stmt1; 
    DEALLOCATE PREPARE stmt1; 

END$$ 
DELIMITER ; 
+1

谢谢。这在mysql中有效。 – Yada 2012-04-13 14:31:53