私はPL/SQLにかなり慣れていないので、少し作業する必要があります。かなり似ているいくつかの関数を作成する必要がありました。この質問のために単純化しました。
いくつかのデータを含む 2 つのテーブル (この例では TABLE1、TABLE2 と呼びます) を取得しました。データをトリミングして検証し、他のテーブルに挿入する必要があります。
TABLE1 -> TABLE3 TABLE2 -> TABLE4
TABLE1 にはいくつかの注文があり、TABLE2 には注文ごとにいくつかのポジションがあります。簡略化したと言ったので、例外やオープン/クローズカーソルなどは投稿していません.ATMはこのように機能しますが、この構造は「ベストプラクティス」に近いとは思いませんが、見つかりませんでしたこの問題をカバーした Web 上の任意の PL/SQL コード。
COMMIT は、おそらく関数全体の後でも、外側のループの最後にある可能性があります。
それで、このままでいいのか、それとも完全にばかげているのか、そして何を変えるべき/変えることができるのか、そしてその理由を教えていただけますか. 「悪い」コーディングスタイルに慣れたくないので、初心者のうちに正しい方法で学びたい.
簡略化されたコードは次のとおりです。
BEGIN
SAVEPOINT SAVE_Stufe_5;
LOOP
SAVEPOINT SAVE_LOOP;
FETCH CURSOR1 INTO RECORD1;
EXIT WHEN CURSOR1%NOTFOUND OR CURSOR1%NOTFOUND IS NULL;
vError := 0;
RECORD1 := CURSOR1;
-- DATAVALIDATION (vError will be the Errorcode)
IF (vError = 0) THEN
retcode := InsertTABLE3(RECORD1);
IF (retcode != DATABASE_OK) THEN
ROLLBACK TO SAVE_LOOP;
END IF;
END IF;
LOOP
FETCH CURSOR2 INTO CURSOR2;
EXIT WHEN CURSOR2%NOTFOUND OR CURSOR2%NOTFOUND IS NULL OR vError != 0 OR retcode != DATABASE_OK;
RECORD2 := CURSOR2;
-- DATAVALIDATION (vError will be the Errorcode)
IF (vError = 0) THEN
retcode := InsertTABLE4(RECORD2);
IF (retcode = DATABASE_OK) THEN
UPDATE TABLE2
SET TABLE2.Status = 20
WHERE TABLE2.ID = CURSOR2.ID;
ELSE
ROLLBACK TO SAVE_LOOP;
END IF;
END IF;
END LOOP;
IF (vError = 0) THEN
UPDATE TABLE1
SET TABLE1.Status = 20
WHERE TABLE1.ID = CURSOR1.ID
ELSE
ROLLBACK TO SAVE_LOOP;
UPDATE TABLE1
SET TABLE1.Status = vError
WHERE TABLE1.ID = CURSOR1.ID
UPDATE TABLE2
SET TABLE2.Status = vError
WHERE TABLE2.ID = CURSOR2.ID
END IF;
END LOOP;
END;
小さな更新:
データを他のテーブルに取得する方法がよくわかりませんが、検証セットベースを実行することができました。トリムを含む挿入選択を試みましたが、1 行しか挿入されません。示唆されているように暗黙のカーソルを使用する場合は、まだループする必要があります。カーソルをループするのではなく、暗黙のカーソルが 1 行しかない限り、SELECT INTO をループします。
私を助けるために、スニペットまたはリンクが本当に必要になると思います。これが私の試みの簡略化されたバージョンです:
INSERT INTO TABLE3
(
val1,
val2,
val3
)
SELECT TRIM(val1),
TRIM(val2),
TRIM(val3),
FROM TABLE1
WHERE STATUS = 10
AND (TRIM(PK1) || TRIM(PK2)) NOT IN (SELECT (TABLE3.PK1 || TABLE3.PK2) FROM TABLE3);