0

2 つのネストされたカーソルを持つ sp があります。外側のカーソルは顧客、内側のカーソルはピリオドです。内部カーソルでエラーが発生した場合、特定の顧客に対して行われたことをロールバックして、次の顧客の処理を続行したい。ただし、次の顧客に対して内側のカーソルが実行されると (例外が発生した後)、「カーソルは既に開いています」というメッセージが表示されます。

コードは次のようになります。

    DECLARE customers CURSOR FOR
    select * from customers_table;

    DECLARE CONTINUE HANDLER FOR NOT FOUND
    SET no_more_customers = 1;

    OPEN customers;

    customers_cursor:
    REPEAT
    FETCH customers
    INTO ....

    IF no_more_customers = 1
    THEN
        close customers;
        LEAVE customers_cursor;
    END IF;

    BEGIN
        DECLARE EXIT HANDLER FOR SQLEXCEPTION
        BEGIN
        rollback;
    END;

    ....... //do some stuff

    BEGIN
        DECLARE no_more_periods INT(1) DEFAULT 0;
        DECLARE periods CURSOR FOR
            SELECT ...

        DECLARE CONTINUE HANDLER FOR NOT FOUND
        SET no_more_periods = 1;

        OPEN periods;

        periods_cursor:
        REPEAT
        FETCH periods INTO...

        IF no_more_periods = 1
        THEN
            close periods;
            LEAVE periods_cursor;
        END IF;

    ..... //do some stuff point 1

        UNTIL no_more_periods = 1
        END REPEAT periods_cursor;
        end;

    END;    

    UNTIL no_more_customers = 1
    END REPEAT customers_cursor;
END;

顧客 1 が実行され、 で例外が発生し//do some stuff point 1ます。open periods次に、ステートメントに到達するまで顧客2が実行され、 「カーソルがすでに開いています」というメッセージが表示されます。

どうもありがとうございました。

4

2 に答える 2

0

コードにトランザクションやコミットが見当たりません。以下を含むようにコードを変更します。

  • 顧客ごとに新しいトランザクションを開始する
  • 次の顧客を開始する前に、このトランザクションをコミットします。
  • ロールバックを実行する前に、期間カーソルを閉じます。
于 2013-03-09T23:44:13.297 に答える
0

@JodyT さん、ご協力ありがとうございます。顧客カーソルのループごとに新しいブロックを開始しています (「if no_more_customer=1」ブロックの後に開始します)。また、次の顧客の前に「コミット」を行っています。残念ながら、閉じることができませんこのブロックの例外ハンドラーの期間カーソル (このスコープコンパイル時のエラーで定義されていないカーソル期間)。問題を克服するために私がしたことは、内側のループ内に例外ハンドラーを定義することでした (期間カーソルの続行ハンドラーの直後)。 )。このハンドラーでは、期間を閉じてから、例外を発生させて、外側の例外ハンドラーでロールバックを実行します

于 2013-03-10T16:27:46.760 に答える