代码之家  ›  专栏  ›  技术社区  ›  spinjector

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

  •  0
  • spinjector  · 技术社区  · 6 年前

    我想运行一个查询,为定期更改的表名列表获取实时数据和元数据的组合。这是为了研究;在一个大型服务器上进行分析,每个服务器上有100多个模式和数千个表/视图。我需要帮助动态引用表名,我知道这是不可能的。然而。。。

    下面是我希望做的一个基本示例,但它当然行不通:

    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 回复  |  直到 6 年前
        1
  •  2
  •   Charles    6 年前

    动态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');