0

こんばんは

クラッシュして上記のエラーが発生した定期的にテーブルにデータを入力するスクリプトがあります。奇妙なことに、本番システムで問題なく 3 か月近く実行されていたのに、先週突然クラッシュしました。私の知る限り、テーブルに変更はありません。

誰もこのようなことに遭遇したことがありますか?私が実装している集計関数と関係があると思います。しかし、最初はうまくいきました。

お願いします; エラーが発生すると思われる手順に開発したスクリプトの一部を添付してください。

手順の作成または置換 V1 は

- 宣言する

    v_a       VARCHAR2(4000);
    v_b       VARCHAR2(4000);
    v_c       VARCHAR2(4000);
    v_d       VARCHAR2(4000);
    v_e       VARCHAR2(4000);
    v_f       VARCHAR2(4000);
    v_g       VARCHAR2(4000);
    v_h       VARCHAR2(4000);
    v_i       VARCHAR2(4000);
    v_j       VARCHAR2(4000);
    v_k       VARCHAR2(4000);
    v_l       VARCHAR2(4000);
    v_m       VARCHAR2(4000);
    v_n       NUMBER(10);
    v_o       VARCHAR2(4000);

--
-- DEMO テーブルに入力する手順

        BEGIN

              -- Delete all from the DEMO table
              DELETE FROM DEMO;

              -- Populate fields in DEMO from DEMOV1
              INSERT INTO DEMO(ID, D_ID, CTR_ID, C_ID, DT_NAM, TP, BYR, ENY,
                               ONG, SUMM, DTW, REV, LD, MD, STAT, CRD)
              SELECT ID, D_ID, CTR_ID, C_ID, DT_NAM, TP, TO_NUMBER(TO_CHAR(BYR,'YYYY')), 
                   TO_NUMBER(TO_CHAR(NVL(ENY,SYSDATE),'YYYY')), CASE WHEN ENY IS NULL THEN 'Y' ELSE 'N' END, SUMMARY, DTW,
                   REV, LD, MD, '1', SYSDATE 
              FROM DEMOV1;

          -- LOOP THROUGH DEMO TABLE
          FOR j IN (SELECT ID, CTR_ID, C_ID FROM DEMO)
          LOOP




                Select semic_concat(TXTDESC)
                INTO v_a 
                From GEOT
                WHERE ID = j.ID;



               SELECT COUNT(*)
               INTO v_n
               FROM MERP M, PROJ P
               WHERE M.MID = P.COD
               AND ID = j.ID
               AND PROAC IS NULL;

               IF (v_n > 0)
               THEN


                    Select semic_concat(PRO)
                    INTO v_b 
                    FROM MERP M, PROJ P
                    WHERE M.MID = P.COD
                    AND ID = j.ID;

               ELSE


                    Select semic_concat(PRO || '(' || PROAC || ')' )
                    INTO v_b 
                    FROM MERP M, PROJ P
                    WHERE M.MID = P.COD
                    AND ID = j.ID;

               END IF;


                Select semic_concat(VOCNAME('P02',COD))
                INTO v_c 
                From PAR
                WHERE ID = j.ID;



                Select semic_concat(VOCNAME('L05',COD))
                INTO v_d 
                From INST
                WHERE ID = j.ID;


                Select semic_concat(NVL(AUTHOR,'Anon') ||' ('||to_char(PUB,'YYYY')||') '||TITLE||', '||EDT)
                INTO v_e 
                From REFE
                WHERE ID = j.ID;



                Select semic_concat(NAM)
                INTO v_f 
                FROM EDM E, EDO EO
                WHERE E.EDMID = EO.EDOID
                AND ID = j.ID;



                Select semic_concat(VOCNAME('L08', COD))
                INTO v_g 
                FROM AVA 
                WHERE ID = j.ID;



               SELECT or_concat(NAM)
               INTO v_o
               FROM CON 
               WHERE ID = j.ID
               AND NAM = 'Unknown';

                    IF (v_o = 'Unknown')
                    THEN

                        Select or_concat(JOBTITLE || ' (' || EMAIL || ')')
                        INTO v_h 
                        FROM CON 
                        WHERE ID = j.ID;

                    ELSE

                        Select or_concat(NAM || ' (' || EMAIL || ')')
                        INTO v_h 
                        FROM CON 
                        WHERE ID = j.ID;

                    END IF;



                Select commaencap_concat(COD)
                INTO v_i 
                FROM PAR 
                WHERE ID = j.ID;

                IF (v_i = ',')
                THEN

                    v_i := null;

                ELSE

                    Select commaencap_concat(COD)
                    INTO v_i 
                    FROM PAR 
                    WHERE ID = j.ID;


                END IF;



                Select commaencap_concat(COD)
                INTO v_j 
                FROM INST 
                WHERE ID = j.ID;

                IF (v_j = ',')
                THEN

                    v_j := null;

                ELSE

                    Select commaencap_concat(COD)
                    INTO v_j 
                    FROM INST
                    WHERE ID = j.ID;

                END IF;



                Select commaencap_concat(COD)
                    INTO v_k 
                    FROM SAR 
                    WHERE ID = j.ID;

                IF (v_k = ',')
                THEN

                    v_k := null;

                ELSE

                    Select commaencap_concat(COD)
                    INTO v_k 
                    FROM SAR 
                    WHERE ID = j.ID;

                END IF;




                Select commaencap_concat(CONID)
                    INTO v_l 
                    FROM CON 
                    WHERE ID = j.ID;

                IF (v_l = ',')
                THEN

                    v_l := null;

                ELSE

                    Select commaencap_concat(CONID)
                    INTO v_l 
                    FROM CON 
                    WHERE ID = j.ID;

                END IF;



                Select commaencap_concat(PROID)
                    INTO v_m 
                    FROM PRO 
                    WHERE ID = j.ID;

                IF (v_m = ',')
                THEN

                    v_m := null;

                ELSE

                    Select commaencap_concat(PROID)
                    INTO v_m 
                    FROM PRO 
                    WHERE ID = j.ID;

                END IF;

                 -- UPDATE DEMO TABLE
                 UPDATE DEMO
                 SET GEOC = v_a,
                     PRO = v_b,
                     PAR = v_c,
                     INS = v_d,
                     REFER = v_e,
                     ORGR = v_f,
                     AVAY = v_g,
                     CON = v_h,
                     DTH = v_i,
                     INST = v_j,
                     SA = v_k,
                     CC = v_l,
                     EDPR = v_m,
                     CTR = (SELECT NAM
                                  FROM EDM
                                  WHERE EDMID = j.CTR_ID),
                     COLL = (SELECT NAM
                                    FROM EDM
                                    WHERE EDMID = j.C_ID)

                WHERE ID = j.ID;

          END LOOP;


        END V1;

/

集約関数、commaencap_concat (コンマでカプセル化)、or_concat (or で連結)、および semic_concat (セミコロンで連結)。

使用される残りのテーブルはすべてメイン テーブル DEMO にリンクされています。

列のサイズを確認しましたが、問題ないようです。SELECT ステートメントを単独で実行しようとしましたが、テーブルにデータを入力せずに同じエラーが発生します。

手がかりはありますか?

予想通りのご支援、誠にありがとうございました。

APC のご協力に感謝します。特に行タイプとデバッグのアドバイス。すべての列を相互にチェックし、サイズが 4000 バイトから 4000 バイト未満の列を作成しましたが、それでも同じエラー メッセージが表示されます。

私が試した SELECT ステートメントは、プロシージャ内にある集計関数の 1 つを使用していました。

            Select semic_concat(TXTDESC)
           -- INTO v_a 
            From GEOT
            WHERE ID IN (SELECT ID FROM DEMO);

そして、文字列バッファが小さすぎるという同じエラーが発生しました。しかし、ステートメントにgroup byを追加すると、うまくいきました。

            Select semic_concat(TXTDESC)
            -- INTO v_a 
            From GEOT
            WHERE ID IN (SELECT ID FROM DEMO)
            GROUP BY ID;

プロシージャ内のそのようなステートメントのすべての出現を交換しようとしましたが、それでも同じエラーが発生します。もう一度ありがとう; まだ取り組んでいます。

4

1 に答える 1

5

集約関数、ええと、集約。つまり、数値を追加したり、文字列を連結したりします。ソース値が大きいほど、集計された製品は大きくなります。

詳細を知らなければ断言することはできませんが、最も可能性の高い説明は、データ内の何かが変更され、その結果、集計値が大きすぎてターゲット列に収まらないということです。

編集

「 SELECT ステートメントを単独で試してみましたが、同じエラーが発生しました...」

うーん、どのSELECT?あなたの手順にはそれらがたくさんあります。

とにかく、あなたがしなければならないことは、あなたのコードをデバッグすることを学ぶことです. (1)

PL/SQL をデバッグする最善の方法は、そのような試みをサポートする IDE を使用することです。TOAD と PL/SQL Developer の両方がこれを行い、Oracle 自身の (無料の) 製品である SQL Developer も同様です。 詳細をご覧ください

または、DBMS_OUTPUT (AKA 悪魔のデバッガー) を使用し、多くのDBMS_OUTPUT.PUT_LINE()呼び出しを補間して、実行しようとしているステートメントと、関連する値の長さを確認することもできます。

ただし、すべての PL/SQL 文字列変数が SQL 列の最大長であることを考えると、変数を設定varchar2(4000)するコードに焦点を当てv_nます。 number(10)SQL で保持できる最大数ではないため、最も可能性の高い候補と思われるバッファ制限に違反しています。ただし、エラー メッセージには文字列バッファーが記載されているため、バム ステアを販売している可能性があります。

もう 1 つの可能性は、最後の UPDATE ステートメントです。DEMO のすべての列のサイズはvarchar2(4000)ですか? そうでない場合は、それらを見る必要があります。%TYPE 構文を使用して変数を指定することをお勧めします。

 v_a demo.geoc%TYPE;
 v_b demo.pro%TYPE;

または、入力を節約するために、単一のレコード変数を指定します。

v_demo demo%rowtype;

次のように参照できます。

select semic_concat(TXTDESC) 
into v_demo.geoc  
From GEOT 
WHERE ID = j.ID; 

(ちなみに、構文を使用して更新ステートメントで行レベル変数を使用することは可能ですUPDATE ... SET ROW =が、あなたの状況では適切ではないと思います。)

編集 2

繰り返しNO_DATA_FOUNDますが、データの問題を指摘しています。データベースが読み取り専用でない限り、データが変更されることを想定する必要があり、データ関連の例外を処理する必要があります。処理しない理由がNO_DATA_FOUND、データが常に存在する必要があるためである場合は、外部キーが見つからないか無効になっているなど、より広範な問題が発生している可能性があります。NO_DATA_FOUND一般に、TOO_MANY_ROWS、 などを取得し、関連する詳細をログに記録するのに役立つ例外ハンドラを含めると想定する方が安全です。


footnote (1) または、単体テスト ハーネスを使用してテストを開始します。

于 2010-06-09T11:21:45.980 に答える