SQLRPGLE游标在按ASC顺序排序时正确返回,但在按DESC排序时什么都不返回,为什么?

问题描述 投票:1回答:3

我正在用IBM RDI进行编码,并在5250仿真器上运行该程序。我正在编写一个简单程序,该程序从单个SQL表读取并将结果输出到打印机文件。该代码基本上可以按预期工作,但是遇到了一些奇怪的事情。当我尝试按desc顺序对游标select语句进行排序时,它返回空值,但是当我不按或按ASC进行排序时,它可以正常工作。我不明白发生了什么。我真的很想解释。

下面的代码。


       DCL-F BOOKRPT2 PRINTER OFLIND(*IN01);

       DCL-S INDGENRE BINDEC(4:0);
       DCL-S CATEGORY CHAR(30);
       DCL-S TOTALRECORDS PACKED(5:0);
       DCL-S TOTALCOST ZONED(5:2);
       DCL-S EOF   IND;
       DCL-S DUMMY ZONED(1);

       DCL-DS BOOKRECORD;
         BOOK CHAR(50);
         DURATION TIME(*ISO);
         AUTHOR CHAR(30);
         BOOKID ZONED(7:0);
         PRICE PACKED(5:2);
         GENRE CHAR(20);
       END-DS;
       //DCL-DS AUDIBLEBKS EXT END-DS;
        //**************************************************************************
        //*                        ***   M A I N   R O U T I N E   ***
        //**************************************************************************
        EXSR PREPFILES;
        EXSR GETSYS;
        WRITE TITLE;
        WRITE COLHDG;
        EXSR GETROW;
        WRITE GENREREC;
        CATEGORY = GENRE;
        DOW NOT EOF;

        IF *IN01 = *ON;
           WRITE TITLE;
           WRITE COLHDG;

          *IN01 = *OFF;
        ENDIF;
          IF CATEGORY = GENRE;
            WRITE DETAIL;
            TOTALRECORDS +=1;
            TOTALCOST += PRICE;
         ELSE;

           WRITE TOTALS;
           CATEGORY = GENRE;
           WRITE GENREREC;
           TOTALRECORDS = 0;
           TOTALCOST = 0;
          ENDIF;
           TOTALBOOKS = TOTALRECORDS;
           TOTALPRICE = TOTALCOST;
        EXSR GETROW;
        ENDDO;
        WRITE TOTALS;
        EXSR WRAPUP;
        *INLR = *ON;
        RETURN;

       BEGSR PREPFILES;
         EXEC SQL
         DECLARE BOOKCURSOR  CURSOR
           FOR
            SELECT BOOK, DURATION, AUTHOR, BOOKID, PRICE, GENRE
            FROM BCI433LIB/AUDIBLEBKS
             ORDER BY GENRE DESC;
         //FOR READ ONLY;
           EXEC SQL
             OPEN  BOOKCURSOR;
                 IF SQLCODE <> 0 OR SQLWN0='W';
                   EOF = *ON;
                 ENDIF;
       ENDSR;

        BEGSR GETROW;
          EXEC SQL
            FETCH NEXT
              FROM BOOKCURSOR
              INTO :BOOKRECORD;
           IF SQLCODE <> 0 OR SQLWN0 = 'W';
              EOF = *ON;
            ENDIF;
        ENDSR;

        BEGSR WRAPUP;
           EXEC SQL
               CLOSE BOOKCURSOR;

             IF SQLCODE <> 0  OR SQLWN0 ='W';
               EOF = *ON;
             ENDIF;
        ENDSR;

        BEGSR GETSYS;
         EXEC SQL
         SELECT CURRENT SERVER, CURRENT DATE
           INTO :SYSTEMNAME, :REPORTDATE
         from SYSIBM/SYSDummy1;
        ENDSR; 

No Order By

with DESC order By

sql ibm-midrange rpgle
3个回答
1
投票

除了代码格式化问题之外,我看到的最可能的答案是,当您按ASC排序时,查询中的最后一条记录存在问题,而当您按DESC排序时,它是第一个记录问题。如其他答案所述,应该通过查看SQLSTATE轻松检查。最快的方法是在RDi调试器中或通过STRDBG运行它。


0
投票

IMO,您的程序应始终检查SQLSTATE并具有处理异常SQLSTATE值的代码。它可能正在写入作业日志,发送电子邮件警报等。

If SQLSTATE <> '00000'; // sucess
  // handle abnormal condition
Endif;

如果您无法/不会更改代码,请使用RDi调试代码并在每次操作后检查SQLSTATE。


0
投票

正如其他人所说,您应该检查SQL状态,但是我忽略警告。光标的最后一行很有可能引起警告而不是错误。因此STRSQL会显示记录,但是由于您不满意警告(但未指出警告可能),因此您什么也收不到。

这是我在程序中几乎所有SQL语句之后都放置的错误检查代码。

exec sql
  ...
if %subst(sqlstate: 1: 2) < '00' or %subst(sqlstate: 1: 2) > '02';
  exec sql get diagnostics condition 1
    :message = message_test;
  SendSqlMsg(message);
endif;

这里有一些说明,消息是varchar(6000),SendSqlMsg()是我编写的用于发送转义消息的子过程。

关于SQLSTATE类的更多说明(SQLSTATE的前两个字符:

  • 00-正常完成
  • 01-警告
  • 02-无数据

其他一切都是错误。

还有一个说明,我说过我实际上在每个SQL语句之后都放了这个,但是在结束游标之后我不检查它。这就是原因。 CLOSE引发的唯一状态是“光标已关闭”。我不在乎关闭游标是否由于这个原因而失败,因为我希望关闭游标,并且它已关闭,没问题。

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