2013-03-13 65 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

相關問題