在ILE RPG中检查sql发现条件的正确方法是什么?

时间:2013-03-13 15:40:48

标签: rpgle db2-400 embedded-sql

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

但检查这些值的正确方法是什么?有人建议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

我正在寻找正确的返回语句,这将使我在没有错误发生时浏览所有行并让我在发生错误时离开。奖励积分可以检查错误。

3 个答案:

答案 0 :(得分:6)

SQLSTATE更好,IBM推荐。

来自IBM的信息中心SQL Messages and Codes Reference: SQLCODE and SQLSTATE concepts

  

SQLSTATE是首选的标准返回码。

SQLSTATE是5个字符,前两个字节标识class of conditions

  • '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;

答案 1 :(得分: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

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

答案 2 :(得分:0)

我对该主题进行了更多搜索,找到something on IBM's site(引用):

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

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