如何将视图获取的表列表传入SQL查询的FROM子句?
动态查询指定Schema下所有表的指定字段
要实现从information_schema.tables获取目标表列表,再自动拼接执行等价于SELECT attribute1 FROM table1, table2, table3的查询,核心是用动态SQL来拼接表名,以下是主流数据库的实现方案:
MySQL 实现(存储过程)
通过游标遍历获取表名,拼接成表列表后构造动态SQL执行:
DELIMITER // CREATE PROCEDURE SelectFromMatchingTables() BEGIN DECLARE tableList VARCHAR(1000); DECLARE done INT DEFAULT FALSE; DECLARE tblName VARCHAR(255); -- 定义游标获取目标表名 DECLARE cur CURSOR FOR SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'my_scheme'; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; SET tableList = ''; -- 遍历游标拼接表名字符串 OPEN cur; read_loop: LOOP FETCH cur INTO tblName; IF done THEN LEAVE read_loop; END IF; SET tableList = IF(tableList = '', tblName, CONCAT(tableList, ', ', tblName)); END LOOP; CLOSE cur; -- 构造并执行动态查询 SET @sql = CONCAT('SELECT attribute1 FROM ', tableList); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END // DELIMITER ;
调用方式
CALL SelectFromMatchingTables();
PostgreSQL 实现(自定义函数)
用PL/pgSQL遍历表名并拼接动态SQL,返回查询结果:
CREATE OR REPLACE FUNCTION select_from_matching_tables() RETURNS SETOF text AS $$ DECLARE tblName text; sql text := 'SELECT attribute1 FROM '; first_table boolean := TRUE; BEGIN -- 遍历获取目标表名 FOR tblName IN SELECT table_name FROM information_schema.tables WHERE table_schema = 'my_scheme' LOOP IF first_table THEN sql := sql || tblName; first_table := FALSE; ELSE sql := sql || ', ' || tblName; END IF; END LOOP; -- 执行动态SQL并返回结果 RETURN QUERY EXECUTE sql; END; $$ LANGUAGE plpgsql;
调用方式
SELECT * FROM select_from_matching_tables();
注意事项
- 确保所有目标表都存在
attribute1字段,否则执行会抛出字段不存在的错误 - 如果表名包含特殊字符(空格、关键字等),需要用标识符包裹:
- MySQL:在拼接时用反引号包裹表名,比如
CONCAT(tableList, ',', tblName, '') - PostgreSQL:用双引号包裹表名,比如
sql := sql || ', "' || tblName || '"';
- MySQL:在拼接时用反引号包裹表名,比如
- 执行该操作需要拥有
information_schema.tables的查询权限,以及目标表的SELECT权限
内容的提问来源于stack exchange,提问作者Astrogrammer
相关产品推荐
相关产品推荐

