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

问题描述 投票:8回答:6

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

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

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

有谁知道我做错了什么?


UPDATE

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

  1. 创建了一个源物理文件(使用CRTSRCPF):QSQLSRC,并创建了一个名为SQLLEAGSEA的成员,其类型为TXT,其中包含SQL语句。
  2. 创建了另一个源物理文件:QCLSRC,并创建了一个名为POPLEAGSEA的成员,其类型为CLP,将当前库更改为ALLOCATE,然后使用RUNSQLSTM运行查询(下面有更多详细信息)。这是实际的命令: RUNSQLSTM SRCFILE(QSQLSRC)SRCMBR(SQLLEAGSEA)COMMIT(* NONE)命名(* SYS)
  3. 将CLP添加到计划作业(使用ADDJOBSCDE),运行以下命令:

CALL PGM(ALLOCATE / POPLEAGSEA)

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

插入ALLOCATE / LEAGSEAS

选择...... BLAH BLAH BLAH ......

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

再次感谢大家!

sql ibm-midrange db2-400
6个回答
4
投票

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

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

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

例如:

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

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


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命令。

通过在命令前放置前缀“CL:”,可以将STRQMQRY命令嵌入到RUNSQLSTM脚本中。由于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 Forms,CRTQMFORM编译器将使用81列,因此RCDLEN(93)建议使用QQMFORMSRC。


2
投票

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


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语句的几种方法的清晰示例。


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


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程序往往更容易阅读。

© www.soinside.com 2019 - 2024. All rights reserved.