7

RPG で組み込み SQL を使用する場合、多くの場合dow、結果のすべての行を処理するためにカーソルとループが発生します。ループ内の条件は、SQLRPGLE プログラムでグローバルに使用可能ないくつかの変数SQLCODおよび/またはに何らかの形で依存していますか?SQLSTT

しかし、これらの値を確認する正しい方法は何ですか? SQLCOD = 0他の人を提案する人もいnot (SQLCOD = +100 or SQLSTT = '02000')ます。1 つはすべての警告で失敗し、もう 1 つは一部のエラーで失敗しないため、満足できません。

私がいくつかのコードで何をするかを説明するには:

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 ステートメントを探しています。これにより、エラーが発生しない場合はすべての行を通過し、エラーが発生した場合は離れることができます。エラーをチェックするための適切な方法に対するボーナスポイント。

4

3 に答える 3

5

SQLSTATE の方が優れており、IBM が推奨しています。

IBM の InfoCenter SQL Messages and Codes Reference から: SQLCODE および SQLSTATE の概念

SQLSTATE は推奨される標準リターン コードです。

SQLSTATE は 5 文字で、最初の 2 バイトが状態のクラスを識別します。

  • '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 を処理し、予期しないものを処理する例外コードを追加することです。1 つの実装:

  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 に答える