Mysql 如何基于变量选择模式?
考虑:Mysql 如何基于变量选择模式?,mysql,sql,Mysql,Sql,考虑: 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` (`
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”附近使用的正确语法`
据我所知,我是按照法律办事的。然而MySQL说这是不允许的。这是MySQL的一些限制(不允许使用变量作为标识符)还是其他什么?您必须使用prepare语句/dynamic sql来完成这项工作 本文非常详细地介绍了这两个方面: 试试这个:
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;
文件规定:
用户变量可以从一组有限的数据类型中分配一个值:整数、十进制、浮点、二进制或非二进制字符串或空值
您正在尝试将变量用作对象。这不受支持。我建议您编写一个存储过程:
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 ;
我不知道如何将什么分配给变量控制变量的使用位置。您将其作为对象使用,这意味着
@REFRESHDB
的值是一个模式对象,而不是实际的字符串值。我给您和Abe在这一点上的投票权。如果没有动态SQL(Abe为我们提供了一种使用DSQL的方法),MySQL语法就无法做到这一点,这实际上是一件好事,因为它简化了安全性和性能方面的考虑。对于那些走在野外的人来说,DSQL是存在的。它在CREATE TABLE语句上失败了,而不是insert。CREATE TABLE语句失败了。哦,我错过了这一点,你也必须将其放入一个准备好的语句中。我已经对它进行了更新,将create表放在一个准备好的语句中。通过这一更正,您所拥有的一切都是有效的,但是对于任何想要实现这一点的人来说,请注意安全和性能方面的考虑。动态SQL可能有点像黑色艺术。