Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何基于变量选择模式?_Mysql_Sql - Fatal编程技术网

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可能有点像黑色艺术。