如何在as400上以编程方式运行复杂查询?

时间:2012-10-16 19:54:39

标签: sql ibm-midrange db2-400

我是as400的新手,我有一个查询4个表的连接。查询本身很好,它在STRSQL中运行并显示结果。

我正在努力解决的问题是让查询能够以编程方式运行(最终将从预定的CL脚本运行)。

我尝试创建一个物理文件,其中包含使用RUNQRY运行它的查询,但它只显示查询本身,而不是实际结果集。

有谁知道我做错了什么?


更新

感谢大家的指导和资源,我们能够实现目标。如果它对任何人有帮助,这就是我最终做的事情(所有这些都是在它自己的库中完成的,ALLOCATE):

  1. 创建了一个源物理文件(使用CRTSRCPF):QSQLSRC,并创建了一个名为SQLLEAGSEA的成员,其类型为TXT,其中包含SQL语句。

  2. 创建了另一个源物理文件:QCLSRC,并创建了一个名为POPLEAGSEA的成员,其类型为CLP,将当前库更改为ALLOCATE,然后使用RUNSQLSTM运行查询(下面有更多详细信息)。这是实际的命令:

    RUNSQLSTM SRCFILE(QSQLSRC)SRCMBR(SQLLEAGSEA)COMMIT(* NONE)NAMING(* SYS)

  3. 将CLP添加到预定作业(使用ADDJOBSCDE),运行以下命令:

  4. CALL PGM(ALLOCATE / POPLEAGSEA)

    关于RUNSQLSTM,我的研究表明我不能使用这个函数,因为它不支持SELECT语句。我没有在我的问题中指出的是我需要对结果做什么 - 我将把结果数据插入到另一个表中(如果我这样做了,我确信帮助可能已经解决了很多问题)更快)。如此有效,我不会做一个SELECT,我的最终结果实际上是一个INSERT。所以我的SQL语句(在SQLLEAGSEA中)以:

    开头

    INSERT INTO   分配/ LEAGSEAS

    选择   ...   等等等等等等   ...

    从我的研究中,我发现RUNSQLSTM不支持SELECT,因为它没有对结果做任何事情的机制。一旦我停止采取婴儿步骤并意识到我需要在同一语句中选择和插入,它解决了我的主要问题。

    再次感谢大家!

6 个答案:

答案 0 :(得分:4)

命令为RUNSQLSTM,以在物理文件成员或流文件中运行静态SQL语句。

它是一个非交互式命令,因此它不会执行尝试返回结果集的sql语句。

如果您想要更多控制权,包括运行交互式语句的能力,请参阅Qshell db2 utility

例如:

QSH CMD('db2 -f /QSYS.LIB/MYLIB.LIB/MYSRCFILE.FILE/MYSQL.MBR')

请注意,db2实用程序仅接受* SQL命名约定。

答案 1 :(得分:4)

QM查询

如果您需要的所有SQL都是单个复杂的SQL语句,这听起来就是这样,那么最好的办法是使用查询管理查询(see QM Query manual here)

结果可以指向显示,假脱机文件或物理文件(即DB2表)。交互式运行时的默认输出是到屏幕,但是在(计划的)批处理作业中运行时,它将默认为假脱机文件报告。

您可以通过WRKQMQRY以提示模式(非常类似于Query / 400)或SQL模式以交互方式创建QM查询。或者,您可以使用CRTQMQRY命令从源编译QM查询 要运行QM查询,请STRQMQRY命令。

RUNSQL cmd

如果您使用的系统IBM i 7.1完全是最新的,并且安装了Technology Refresh 4(TR4),那么您也可以使用新的RUNSQL命令来执行单个语句。 (see discussion in developerWorks)

SQL Scripting w / RUNSQLSTM cmd

从CL,您可以从源文件成员运行多个SQL语句的SQL脚本。没有标准的默认源文件名,但通常使用QSQLSRC。源成员可以包含多个非交互式SQL语句。这意味着您不能(直接)使用SELECT语句,因为理论上它不知道将结果发送到何处。如果给出CL:前缀,则甚至允许CL命令。 SQL和CL语句都应以分号;结束。虽然SQL语句无法直接向屏幕显示数据,但相同的限制不适用于脚本化的CL命令。

STRQMQRY命令可以嵌入RUNSQLSTM脚本中,方法是在命令前放置前缀“CL:”。由于STRQMQRY可以将输出定向到屏幕,报表或输出表,因此这非常有用。

请记住,要将SELECT查询的输出定向到文件,可以使用INSERT或CREATE TABLE语句。

CREATE TABLE newtbl AS
  ( full-select )
  WITH DATA;

或者,将结果放入您在作业的QTEMP库中创建的表中:

DECLARE GLOBAL TEMPORARY TABLE AS
  ( full-select )
  WITH DATA;

[注意:如果您创建要由CRTQMQRY使用的源,建议您将其创建为CRTSRCPF yourlib/QQMQRYSRC RCDLEN(91),因为编译器将只使用79列源数据(添加12列为序列和更改日期= 91)。但是,对于可用于提供其他格式的QM表单,CRTQMFORM编译器将使用81列,因此建议将RCDLEN(93)用于QQMFORMSRC。]

答案 2 :(得分:2)

RUNQRY是一个实用程序,它允许您执行由另一个名为WRKQRY的实用程序创建的查询。如果你真的想要处理文件中保存的SQL语句,请尝试RUNSQLSTM。它使用源物理文件来存储语句,而不是数据库文件。 QQ源物理文件的标准名称是QQMQRYSRC。要创建该文件,请使用CRTSRCPF yourlib / QQMQRYSRC。然后,您可以使用PDM处理该源PF。 WRKMBRPDM yourlib / QQMQRYSRC。使用F6创建新的源成员。使其成为源类型TXT。然后使用选项2启动一个名为SEU的编辑器。将SQL语句复制/粘贴到此编辑器中。 F3保存源。保存源后,使用RUNSQLSTM执行它。

答案 3 :(得分:2)

现在可以在不使用QM Query,RUNSQLSTM或QShell的情况下直接在CL程序中运行SQL。

这篇文章讨论了CL程序中的RUNSQL语句......

http://www.mcpressonline.com/cl/the-cl-corner-introducing-the-new-run-sql-command.html

本文包含有关支持哪些操作系统级别的信息,以及使用RUNSQL语句的几种方法的清晰示例。

答案 4 :(得分:1)

当然有一个完全不同的解决方案:您可以编写和编译包含该语句的程序。它需要更长时间的阅读,特别是如果您是平台的新手,但它应该为您提供最大的灵活性,而不是您对结果的处理。您可以在C,C ++,RPG,RPG / LE,REXX,PL(我不知道,它是什么)和COBOL中使用SQL。这样做,您可以以任何可处理的方式对一个查询的结果做出反应,并根据您获得的内容启动/创建其他查询。

尽管一些老式的RPG程序员尝试拒绝在RPG中存在SQL,但在很多情况下,有可能只用SQL编写RPG程序而没有直接文件访问(没有F-Specs,对于那些了解RPG的人来说) )。

如果您的解决方案适合您,那就完美了。如果您需要做其他事情,请查看此pdf:http://publib.boulder.ibm.com/infocenter/iseries/v5r3/topic/rzajp/rzajp.pdf

与RPG的整合并不算太糟糕。它适用于正常的程序流程。看起来像这样(自由形式):

/free
    // init search values:
    searchval = 'Someguy';
    // so the sql query:
    exec sql
      SELECT colum1, colum2
      INTO :var1, :var2
      FROM somelib/somefile
      WHERE keycol=:searchval;
    // now do something with the values:
    some_proc(var1);
/end-free

在此,var1var2searchval是普通的RPG变量。不需要引用。也适用于数据结构(外部定义,例如,文件本身的记录格式很合适)。当然,你也可以使用游标和循环。我觉得RPG程序往往更容易阅读。

答案 5 :(得分:1)

这将分两步进行:

 RUNSQL SQL('CREATE TABLE QTEMP/REPORT AS (SELECT +         
          EXTRACT_DATE , SYSTEM, ODLBNM, SUM( +              
          OBJSIZE_MB ) AS LIB_SIZE FROM +                    
          ZSYSCOM/DISKRPTHST WHERE ODLBNM LIKE +             
          ''SIS%'' GROUP BY EXTRACT_DATE, SYSTEM, +          
          ODLBNM ORDER BY LIB_SIZE DESC) WITH +              
          DATA') COMMIT(*NONE) DATFMT(*USA) DATSEP(/)        

 RUNQRY     QRYFILE((QTEMP/REPORT)) OUTTYPE(*PRINTER) +          
          OUTFORM(*DETAIL) PRTDFN(*NO) PRTDEV(*PRINT)        

第一步在qtemp中创建一个临时表结果,第二步/第二行在临时表上运行一个adhoc查询到一个假脱机文件。

谢谢, Michael Frilot