迭代MySQL模式
问题描述 我有一个单租户MySQL数据库设置。也就是说,每个客户机都有一个相同的模式 现在我需要为每个客户机运行一个特定的查询。在多租户设置中(所有客户端共享一个模式),这将很容易做到。然而,在我的设置中,我需要迭代模式。更一般地说,我想访问一个模式,其名称由一个变量给出。如何做到这一点 我尝试过的迭代MySQL模式,mysql,stored-procedures,Mysql,Stored Procedures,问题描述 我有一个单租户MySQL数据库设置。也就是说,每个客户机都有一个相同的模式 现在我需要为每个客户机运行一个特定的查询。在多租户设置中(所有客户端共享一个模式),这将很容易做到。然而,在我的设置中,我需要迭代模式。更一般地说,我想访问一个模式,其名称由一个变量给出。如何做到这一点 我尝试过的 如果我尝试使用varSchemaName(其中varSchemaName是varchar 变量),我得到错误消息error 1314:不允许使用 在存储过程中 如果我尝试从varSchemaNam
- 如果我尝试
(其中使用varSchemaName
是varSchemaName
变量),我得到错误消息error 1314:不允许使用 在存储过程中varchar
- 如果我尝试
从varSchemaName.MyTable中选择* 错误代码:1146。表“varSchemaName.MyTable”不存在。显然,MySQL认为
是一个文本,而不是一个 变数varSchemaName
- 您必须首先构建语句
SET @sql = CONCAT('SELECT * FROM ', varSchemaName, '.MyTable');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
您可以阅读有关准备好的语句的更多信息
您可能会尝试将变量用于表名,但这不起作用。这些参数用于where子句中的值等。上面的方法就是正确的方法。基于fancyPants的答案,您可以在另一个过程的循环中调用该过程,该过程查询信息\u schema.tables以识别包含MyTable的数据库,然后使用db名称作为参数调用fancyPants的过程。如果数据库具有一致的命名方案或包含相同命名的对象(听起来像这里的情况),则此方法很容易。结构将类似于:
DELIMITER //
DROP PROCEDURE IF EXISTS mydriver //
CREATE PROCEDURE mydriver()
BEGIN
DECLARE varSchemaName VARCHAR(64);
DECLARE done BOOLEAN;
DECLARE cur CURSOR FOR
SELECT table_schema
FROM information_schema.tables
WHERE table_name = 'MyTable';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur;
read_loop: LOOP
FETCH cur INTO varSchemaName;
IF done THEN
LEAVE read_loop;
CLOSE cur;
END IF;
CALL fancypants_proc(varSchemaName);
END LOOP;
END //
DROP PROCEDURE IF EXISTS fancypants_proc //
CREATE PROCEDURE fancypants_proc(IN varSchemaName VARCHAR(64))
BEGIN
SET @sql = CONCAT('SELECT * FROM ', varSchemaName, '.MyTable');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
CALL mydriver();
谢谢,我自己刚刚尝试过这个,它似乎起作用了。如果我的查询既长又复杂,那么除了将sql代码粘贴到字符串中之外,还有没有更好的方法来声明
@sql
变量呢?恐怕没有更好的方法了。我发现,通过这种方法,您可以查询单租户数据库设置,就像查询多租户一样。这是难以置信的强大,并将解决我的头痛很多。不幸的是,它不能用于发出创建语句。