2013-03-13 53 views
5

在RPG中使用嵌入式SQL时,通常最终会得到一个游标和一个用于处理结果中所有行的回调函数。循环中的条件在某种程度上取决于SQLCOD和/或SQLSTT,SQLRPGLE程序中的一些全局可用变量?在ILE RPG中检查sql找到的条件的正确方法是什么?

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

我在这里寻找正确return语句,这将让我经历的所有行,如果没有出现错误,让我离开的时候,一个错误发生。奖金积分为一些体面的方式来检查错误。

回答

5

SQLSTATE更好,并由IBM推荐。

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

SQLSTATE是优选的标准返回代码。

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

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

还有什么是错误的。我通常只检查'00'。

简单。简单。更便携。

使用SQLCODE常常涉及到的代码列表,恕我直言,比开发人员友好。

实施例:

个人而言,我一般包括定义和这样的代码:

D [email protected]  s    * inz(%addr(SQLState)) 
D xSQLState  ds    5 based([email protected]) 
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; 
+0

小记...它是对于SQLSTATE类来说,不是完全正确的“任何其他错误”。只有为DB2保留的类(并且定义为错误)一定是错误。例如,信号“K1001”只会在应用程序将其作为错误处理时发生错误。 – user2338816 2014-04-16 13:14:32

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 

这应该采取关心数据结束条件并且不能处理所有错误。我不确定是否有一些警告,我应该照顾(不想陷入无限循环,如果有警告导致不能阅读)。

+0

1)I会建议不要在子过程中使用全局变量(如SQLCOD)。当你需要将一个FETCH循环嵌入另一个时,会发生什么?当内部环路到达EOF时,它将不经意地跳出外部环路的出口。将SQLCOD作为参数传递并且问题消失。 – 2013-03-13 17:07:36

+0

2)吞咽错误(如SQLCOD <> 100)是不可取的。如果这是一个CAST错误,并且您正在丢失数据,会发生什么情况? – 2013-03-13 17:09:26

+0

为此目的定义一个过程的一个可以想象的好处是,如果您没有提供特定的逻辑来处理它们,那么可能还包括处理诸如CAST之类的意外错误的通用逻辑。嗯? – WarrenT 2013-03-15 00:37:37

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 

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

+1

以SQL开头的名称由预编译器保留。请参阅[使用SQL的ILE RPG应用程序中的名称](http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/index.jsp?topic=%2Frzajp%2Frzajprpiamco.htm) – WarrenT 2013-03-13 20:10:39

相关问题