2011-09-30 79 views
11

考虑:如何根据变量选择模式?

SET @PREFIX='DEV_'; 

SET @REFRESHDB=CONCAT(@PREFIX,'Refresh'); 

CREATE TABLE @REFRESHDB.`Metadata` 
(
    `Key` VARCHAR(30) NOT NULL, 
    `Value` VARCHAR(30) NOT NULL, 
    PRIMARY KEY (`Key`) 
) ENGINE = InnoDB; 

INSERT INTO @REFRESDB.`Metadata` (`Key`, `Value`) VALUES ("Version", "0"); 

这似乎不是有效的:mysql回来了:

你在你的SQL语法错误;检查对应于你的MySQL服务器版本正确的语法使用近“@ REFRESHDB.`Metadata`

至于我可以告诉我正确地根据the documentation做的事情的手册。但MySQL说这是不允许的。这是MySQL的一些限制(不允许使用变量作为标识符)或其他?

回答

3

文档状态:

“用户变量可以被分配一个值一组有限的数据类型:整型,十进制,浮点型,二进制或非二进制字符串,或NULL值“

您正在尝试将该变量用作对象。这不支持。

+0

我看不出如何将变量控件分配给变量可以使用的地方。 –

+0

您正在使用它作为对象,这意味着'@ REFRESHDB'的值是一个模式对象,而不是它实际的字符串值。 –

+1

Downvoter关心评论? –

8

你将不得不使用准备语句/动态sql来做到这一点。

本文将详细说明这二者都在出色的细节:

http://rpbouman.blogspot.com/2005/11/mysql-5-prepared-statement-syntax-and.html

试试这个:

SET @PREFIX='DEV_'; 

SET @REFRESHDB=CONCAT(@PREFIX,'Refresh'); 

SET @st = CONCAT('CREATE TABLE ', @REFRESHDB,'.`Metadata` 
(
    `Key` VARCHAR(30) NOT NULL, 
    `Value` VARCHAR(30) NOT NULL, 
    PRIMARY KEY (`Key`) 
) ENGINE = InnoDB'); 

PREPARE tStmt FROM @s; 
EXECUTE tStmt; 


SET @s = CONCAT('INSERT INTO ', @PREFIX, '.`Metadata` (`Key`, `Value`) VALUES ("Version", "0")'); 

PREPARE stmt FROM @s; 
EXECUTE stmt; 
+0

的CREATE TABLE语句失败。 –

+0

哦,我错过了,你将不得不把它写入准备好的陈述中。我已经更新它将创建表放入一个准备好的语句中。 –

+0

有了这个修正,你有什么工作,但是对于任何想要实现这个的人来说,要注意安全和性能方面的考虑。 动态SQL可以是一种黑色艺术。 –

0

我建议你写一个存储过程:

DELIMITER $$ 
CREATE PROCEDURE (IN DBname varchar(255) 
       , IN AKey varchar(255) 
       , IN AValue varchar(255)) 
BEGIN 
    DECLARE query VARCHAR(1000); 
    -- First check the DBName against a list of allowed DBnames, 
    -- to prevent SQL-injection with dynamic tablenames. 

    DECLARE NameAllowed BOOLEAN; 
    SELECT 1 INTO NameAllowed WHERE DBName IN ('validDB1','validDB2'); 
    IF (NameAllowed = 1) THEN BEGIN 

    -- DBName is in the whitelist, it's safe to continue. 
    SET query = CONCAT('INSERT INTO ' 
         ,DBName 
         ,'.MetaData (`key`,`value`) values (?,?)); 
    -- note the use of parameter placeholders, to prevent SQL-injection. 
    PREPARE stmt FROM query; 
    EXECUTE stmt USING Akey, AValue; 
    DEALLOCATE PREPARE stmt; -- clears the query and its result from the cache. 
    END; END IF; 
END $$ 

DELIMITER ; 
+0

它在CREATE TABLE语句上失败,而不是插入。 –

相关问题