7

在 RPG 中使用嵌入式 SQL 时,您通常会使用游标和dow-loop 来处理结果中的所有行。循环中的条件以某种方式依赖于SQLCOD和/或SQLSTTSQLRPGLE 程序中的一些全局可用变量?

但是检查这些值的正确方法是什么?有些人建议SQLCOD = 0其他人not (SQLCOD = +100 or SQLSTT = '02000')。一个在所有警告上都失败了,另一个在某些错误上没有失败,所以我不满意。

为了说明我用一些代码做什么:

Pmain             B
D                 PI
Dmy_ds          E DS                  extname(SOME_TABLE)
D                                     qualified
 /free
  exec sql
    DECLARE cur CURSOR FOR
      SELECT *
      FROM some_table;
  exec sql 
    OPEN cur;
  exec sql
    FETCH cur
     INTO :my_ds;
  dow sql_found();
      exec sql
        FETCH cur
         INTO :my_ds;
  enddo;
  exec sql
    CLOSE cur;
 /end-free
Pmain             E


Psql_found        B
D                 PI              N
 /free
  // insert return statement here...
 /end-free
Psql_found        E

我在这里寻找正确的返回语句,如果没有发生错误,这将使我遍历所有行,并在发生错误时让我离开。一些体面的方法来检查错误的奖励积分。

4

3 回答 3

5

SQLSTATE 更好,IBM 推荐。

来自 IBM 的 InfoCenter SQL 消息和代码参考:SQLCODE 和 SQLSTATE 概念

SQLSTATE 是首选的标准返回码。

SQLSTATE 是 5 个字符,前两个字节标识一类条件

  • '00' = 不合格的成功完成
  • '01' = 警告
  • '02' = 无数据

其他任何事情都是错误。我通常只检查'00'。

简单的。简单的。更便携。

使用 SQLCODE 通常涉及代码列表,恕我直言,这些代码对开发人员不太友好。

例子:

就个人而言,我通常包括这样的定义和代码:

 D xSQLState@      s               *   inz( %addr(SQLState) )
 D xSQLState       ds             5    based(xSQLState@)
 D  xSQLState2                    2a
 D   
 D Success_On_SQL  C                   const('00')
 D Warning_On_SQL  C                   const('01')
 D NoData_On_SQL   C                   const('02')

然后在任何 SQL 操作之后,我一般都会检查

   if xSQLState2 <> Success_On_Sql;
     someflag = true;
   endif;
于 2013-03-13T18:55:47.773 回答
2

最佳实践是处理您期望的 SQLCODE(作为预期处理的一部分)并添加异常代码来处理您不希望的代码。一种实现:

  dow 1=1;  // forever
      exec sql
        FETCH cur
         INTO :my_ds;
  // normal exit         
  if sqlstt = SQL_NODATA;
    SFLEND = *on;        
    leave;               
  endif;                 

  // can't CAST a value
  if sqlstt = SQL_CAST;         // CAST error                               
    ... tell user there's an error and read another
    iter;                                                                  
  endif;                                                                   

  // decimal data error
  if sqlstt = SQL_DDE;
    tell user to call IT and stop reading
    leave;                                      
  endif;                                        


  // whoops! not expected at all.  Dump for post-mortem
  if sqlstt <> SQL_NORMAL;                             
    ... tell user to call IT and stop reading
    dump(a);                             
    leave;                                              
  endif;                                               

  // test for end of loop
  // filled subfile page?
  enddo;  // forever

使用这种类型的实现,您必须故意离开循环;无论您是填充了子文件页面、加载了数组中的最高元素还是遇到了错误。我不确定是否有一个通用的实现可以处理所有情况。如果您有记录锁定,有时您可能想离开读取循环,有时您想发出一条消息并重试(例如)。

于 2013-03-13T17:05:21.790 回答
0

我对该主题进行了更多搜索,并在 IBM 的网站上找到了一些东西(引用):

The SQLCODE is also set by the database manager after each SQL 
statement is executed as follows: 
  - If SQLCODE = 0 and SQLWARN0 is blank, execution was successful.
  - If SQLCODE = 100, no data was found. For example, a FETCH 
    statement returned no data, because the cursor was positioned 
    after the last row of the result table.
  - If SQLCODE > 0 and not = 100, execution was successful with a 
    warning.
  - If SQLCODE = 0 and SQLWARN0 = 'W', execution was successful 
    with a warning.
  - If SQLCODE < 0, execution was not successful.

这会导致我sql_found()这样:

Pfound_sql        B
D                 PI              N
 /free
  return (SQLCOD >= 0) and (SQLCOD<>100);
 /end-free
Pfound_sql        E

这应该处理数据结束条件并在所有错误上失败。我不确定是否有一些我应该注意的警告(不想陷入无限循环,如果有导致不阅读的警告)。

于 2013-03-13T16:05:13.157 回答