0

私は自分のコードで問題を理解できません:

/* Declare a cursor for the FETCH statement. */
EXEC SQL DECLARE customer_cursor CURSOR FOR
SELECT CUSTOMER_ID, CUSTOMER_NAME
FROM CUSTOMER_TABLE 
WHERE CUSTOMER_CARD_NUM = :argv[1];

if ( sqlca.sqlcode != 0 )
{
        printf("Declare cursor failed\n");
        return( sqlca.sqlcode );
}
EXEC SQL OPEN customer_cursor;
if ( sqlca.sqlcode != 0 )
{
        printf("Open cursor failed\n");
        return( sqlca.sqlcode );
}
EXEC SQL WHENEVER NOT FOUND GOTO no_match;

for ( ;; )
{
    /* Fetching data */
    EXEC SQL FETCH customer_cursor 
        INTO :var_customer_id, :var_customer_name;
    if ( sqlca.sqlcode != 0 )
    {
            EXEC SQL CLOSE cust_data_cursor;
            return ( sqlca.sqlcode );
    }

    /* Doing some stuff here */
    processing_customer();

}
EXEC SQL CLOSE customer_cursor;

/* Handling the no data found here */    
no_match:

      printf("NO CUSTOMER MATCHING THIS CARD_NUM\n");
      /* Some stuff */
      ......
      return 1;

私のクエリは1行か何も返さないはずですが、何も返されない場合はすべて問題ありませんが、一致する場合は関数processing_customerが実行され、奇妙なことにno_matchも実行されます

私がそれを修正するのを手伝ってくれてありがとう。

4

3 に答える 3

1

@Roger Cornejoが示唆しているように、一致する場合は「一致なし」セクションを実行しない方法が必要です。no_match:は単なるラベルなので、そのセクションを実行しないようにコードに指示するものは何もありません。そのラベルの前、またはそのgoto後ろに戻る必要があります。一致しないシナリオでは、カーソルを閉じる必要もあります。

しかし、これは不必要に厄介なようで、@ Arionが示唆しているように、これには明示的なカーソルは必要ありません。aを実行しselect intoて例外をキャッチするだけです。

EXEC SQL SELECT CUSTOMER_ID, CUSTOMER_NAME
    INTO :var_customer_id, :var_customer_name
    FROM CUSTOMER_TABLE 
    WHERE CUSTOMER_CARD_NUM = :argv[1];

if (sqlca.sqlcode == 1403)
{
    printf("NO CUSTOMER MATCHING THIS CARD_NUM\n");
    /* Some stuff */
    ......
    return 1;
}
if (sqlca.sqlcode != 0)
{
    return ( sqlca.sqlcode );
}

/* Doing some stuff here */
processing_customer();

行は0行または1行になるとおっしゃいました。複数ある場合は、行が多すぎるというエラー(ORA-02112)が発生します。

于 2012-04-10T10:28:45.363 に答える
0

「EXECSQLCLOSEcustomer_cursor;」の後にGOTOを追加します。

于 2012-04-09T13:19:32.650 に答える
0

ラベル「no_match」を「no_more_records」に変更すると、2回実行される理由がわかります。

a)レコードがない場合、FETCHはすぐにNOT FOUND条件を発生させるため、ラベル「no_more_records」に移動します。

b)1つ(または複数)のレコードがある場合、FETCHが実行され、最初のレコードが返されます。

そうして

if(sqlca.sqlcode!= 0)

false(実際には、他の問題をトラップするためにのみ有用)と評価されてから

processing_customer();

After it, the FETCH run again (by the infinity for) and behave as in (a): no_more_records condition arrives.

于 2013-09-05T18:58:26.223 に答える