Как выбрать схему на основе переменной?
Рассмотрим:
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 (не позволяя использовать переменные как идентификаторы) или что-то еще?
Ответы
Ответ 1
Документация гласит:
"Пользовательским переменным может быть присвоено значение из ограниченного набора типов данных: целочисленная, десятичная, плавающая, двоичная или недвоичная строка или значение NULL"
Вы пытаетесь использовать переменную как объект. Это не поддерживается.
Ответ 2
Для этого вам нужно будет использовать инструкцию prepare/dynamic 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;
Ответ 3
Я предлагаю вам написать хранимую процедуру:
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 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 ;