DB2 SQL 如何利用另一查询结果作为表名编写存储过程实现动态查询
针对Db2 for i的存储过程实现方案
你用到了qsys2.systables系统表,属于IBM i平台的Db2数据库,以下是两种场景的存储过程实现:
场景1:每日仅存在1个符合条件的DAILY开头表
如果确认查询只会返回一个目标表,可使用简化版,调用后直接返回该表的前10行数据:
CREATE OR REPLACE PROCEDURE PTLDBA.GET_DAILY_TABLE_SAMPLE() LANGUAGE SQL DYNAMIC RESULT SETS 1 BEGIN DECLARE v_table_name VARCHAR(200); DECLARE v_sql VARCHAR(500); -- 查询获取当日符合条件的目标表名 SELECT TABLE_SCHEMA || '.' || TABLE_NAME INTO v_table_name FROM qsys2.systables WHERE table_schema = 'PTLDBA' AND TABLE_NAME LIKE 'DAILY%' AND DATE(LAST_ALTERED_TIMESTAMP) = CURRENT DATE FETCH FIRST 1 ROWS ONLY; -- 拼接动态查询SQL SET v_sql = 'SELECT * FROM ' || v_table_name || ' LIMIT 10'; -- 声明返回结果的游标,直接返回给调用客户端 PREPARE stmt FROM v_sql; DECLARE res_cur CURSOR WITH RETURN TO CLIENT FOR stmt; OPEN res_cur; END;
调用方式:
CALL PTLDBA.GET_DAILY_TABLE_SAMPLE();
场景2:每日存在多个符合条件的DAILY开头表
如果需要返回所有符合条件表的前10行数据,可使用以下版本,每个表的查询结果会作为独立结果集返回:
CREATE OR REPLACE PROCEDURE PTLDBA.GET_ALL_DAILY_TABLE_SAMPLE() LANGUAGE SQL DYNAMIC RESULT SETS 100 -- 可根据实际可能的表数量调整最大值 BEGIN DECLARE v_table_name VARCHAR(200); DECLARE v_sql VARCHAR(500); DECLARE v_sqlcode INT DEFAULT 0; -- 游标遍历所有符合条件的表 DECLARE c_tables CURSOR FOR SELECT TABLE_SCHEMA || '.' || TABLE_NAME AS Schema_Table FROM qsys2.systables WHERE table_schema = 'PTLDBA' AND TABLE_NAME LIKE 'DAILY%' AND DATE(LAST_ALTERED_TIMESTAMP) = CURRENT DATE; -- 无匹配表时的异常处理 DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_sqlcode = 100; OPEN c_tables; table_loop: LOOP FETCH c_tables INTO v_table_name; IF v_sqlcode = 100 THEN LEAVE table_loop; END IF; -- 拼接每个表的查询SQL并返回结果 SET v_sql = 'SELECT * FROM ' || v_table_name || ' LIMIT 10'; BEGIN PREPARE stmt FROM v_sql; DECLARE res_cur CURSOR WITH RETURN TO CLIENT FOR stmt; OPEN res_cur; END; END LOOP table_loop; CLOSE c_tables; END;
调用方式:
CALL PTLDBA.GET_ALL_DAILY_TABLE_SAMPLE();
注意事项
- 若表名可能包含特殊字符、空格,拼接SQL时可以给表名加上双引号包裹:
SET v_sql = 'SELECT * FROM "' || v_table_name || '" LIMIT 10'; - 可自行修改
LIMIT 10调整每个表返回的行数 - 存储过程默认创建在
PTLDBAschema下,可根据需求调整存储位置
内容的提问来源于stack exchange,提问作者Buddha532
相关产品推荐
相关产品推荐

