10

我是使用 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),运行以下命令:

呼叫 PGM(分配/POPLEAGSEA)

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

插入分配/LEAGSEAS

选择 ... 呜呜呜呜...

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

再次感谢大家!

4

6 回答 6

5

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

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

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

例如:

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

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

于 2012-10-16T20:30:37.830 回答
4

质量管理查询

如果您需要的所有 SQL 都是单个复杂的 SQL 语句,并且听起来就是这样,那么您最好的选择是使用查询管理查询(请参阅此处的 QM 查询手册)

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

WRKQMQRY您可以通过、在提示模式(很像 Query/400)或 SQL 模式下交互式地创建 QM 查询。CRTQMQRY或者,您可以使用命令从源代码编译 QM 查询。
要运行您的 QM 查询,请使用STRQMQRY命令。

运行 SQL 命令

如果您使用的系统具有完全最新的 IBM i 7.1,并且安装了 Technology Refresh 4 (TR4),那么您还可以使用新RUNSQL命令来执行单个语句。(参见 developerWorks 中的讨论)

使用 RUNSQLSTM cmd 编写 SQL 脚本

在 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 表单,CRTQMFORM编译器将使用 81 列,因此RCDLEN(93)建议用于 QQMFORMSRC。]

于 2012-10-17T22:47:40.527 回答
2

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

于 2012-10-16T20:32:27.837 回答
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 语句的几种方法的清晰示例。

于 2013-01-18T21:43:28.237 回答
1

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

尽管一些老式的 RPG 程序员千方百计否认 RPG 中的 SQL 存在,但今天在许多情况下,编写仅使用 SQL 且没有直接文件访问的 RPG 程序是可能的(对于那些了解 RPG 的人来说,没有 F-Specs)。

如果您的解决方案适合您,那就完美了。如果您需要做其他事情,请尝试查看此 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 程序往往更容易阅读。

于 2012-10-24T12:33:43.173 回答
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 中创建一个临时表结果,第二步/行仅对临时表运行临时查询到假脱机文件。

谢谢,迈克尔弗里洛

于 2013-06-08T19:20:00.717 回答