在DB2 / 400 SQL查询中动态引用表名。

时间:2018-11-07 20:00:32

标签: db2 db2-400 db2-luw

我想运行一个查询,该查询将实时数据和元数据结合在一起以获取定期更改的表名列表。这是用于在大型服务器上进行的研究和分析,该服务器具有100多个模式,每个模式中都有成千上万个表/视图。我需要动态引用表名的帮助,据我了解这是不可能的。但是...

我的Google搜索表明解决方案可能是文本变量中的SQL语句,然后由EXEC语句执行。但这是DB2 / 400 v7r3,这很复杂(就像IBM网站上的SQL参考一样),而且我很难创建正确的语法。

这是我想做的一个基本示例,但是当然不起作用:

SELECT        TABLE_NAME,
              TABLE_TEXT,
              ( SELECT COUNT(*) FROM TABLE_NAME ) AS ROW_COUNT
              -- above line of course does not work
FROM          QSYS2.SYSTABLES
WHERE         TABLE_SCHEMA = 'ABCDEFGH'
AND           TABLE_NAME IN ('ARCMNTST', 'ARIMSGT', 'ARTENT', 'DAILYHT', 'ETC')

我了解我需要以下内容,但我无法找出正确的陈述:

DECLARE       @sqltext AS VARCHAR(128)
SELECT        TABLE_NAME,
              TABLE_TEXT,
              ( SET @sqltext = 'SELECT COUNT(*) FROM ABCDEFGH.' || TABLE_NAME
                EXEC sqltest ) AS ROW_COUNT --this is probably wrong
FROM          QSYS2.SYSTABLES
WHERE         TABLE_SCHEMA = 'ABCDEFGH'
AND           TABLE_NAME IN ('ARCMNTST', 'ARIMSGT', 'ARTENT', 'ETC', 'ETC', 'ETC')
ORDER BY      TABLE_NAME

1 个答案:

答案 0 :(得分:1)

动态SQL并不困难...

基本上,将SQL语句构建到字符串变量中。使用CONCAT包含其他值

@sqlStmt = 'Insert into mytable values (''ConstVal'',' concat SomeVar concat ')';

execute immediate @sqlStmt;

要注意的是,您必须对字符串进行转义,例如上面的'ConstVal'用双单引号引起来。

另一个问题是您不能像尝试那样使用SELECT。如果只有一行要返回,则SELECT INTO将是静态语句的一种选择。但是不支持动态。您必须改为使用动态VALUES INTO

但是,您似乎想要返回多行。在这种情况下,您需要使用游标。不幸的是,动态游标要复杂一些,因为您必须使用SQL描述符。

declare myCursor cursor for myStatement;

set @sqlStmt = 'select ....';
prepare myStatement into mySqlDescriptor from @SqlStmt;

open myCursor;
// done if you are returning the results
// assuming you want to process in your procedure..
// add a loop that does 
//   fetch next from myCursor into myData;

说了这么多,您不需要任何信息就可以获取表的行数... syspartitionstat目录视图已经具有该信息。

select table_name, number_rows 
from syspartitionstat
where table_schema = 'ABCDEFGH' 
      and TABLE_NAME in ('ARCMNTST', 'ARIMSGT', 'ARTENT', 'ETC', 'ETC', 'ETC');