リモートソーステーブルを読み取って、ローカルテーブルを更新する次のスクリプトがあります。スクリプトはエラーなしで正常に実行されています。この投稿は、カーソルの仕組みについて適切に説明することです。
リモート ソース テーブルからデータを読み取りSource_Product
、最初に一時テーブルに挿入しますVW_PRODUCT
。その後、PRODUCT
テーブルを挿入または更新します。
私の質問は。
1) いつproduct_cursor
データをロードしますか? for ループでカーソルを読み取ろうとするときですか? または、カーソルを宣言すると、データがロードされますか?
2) このスクリプトは毎日実行されます。product_cursor
が宣言するとすぐに実行される場合は、VW_PRODUCT
前日のデータがあります。今日のデータはまだVW_PRODUCT
テーブルに挿入されていないためです(挿入クエリはカーソル宣言の後に使用できます)。したがって、 のproduct_cursor
後にはレコードがありませんminus
。ysterday_data
minus
ysterday_data
ゼロなので。PRODUCT
では、以下のスクリプトに従って、どのように最新のデータを更新または挿入できますか?
SET serveroutput ON SIZE 1000000;
DECLARE
CURSOR product_cursor
IS
SELECT V.PRODUCTID,
V.PACKAGEID'
V.ENDDATE
FROM VW_PRODUCT V
MINUS
SELECT E.PRODUCTID,
E.PACKAGEID,
E.ENDDATE
FROM PRODUCT E;
/*The delete data*/
CURSOR product_cursor_del
IS
SELECT E.PRODUCTID FROM PRODUCT E WHERE (E.ENDDATE > SYSDATE OR E.ENDDATE IS NULL)
MINUS
SELECT V.PRODUCTID FROM VW_PRODUCT V;
/* Variable Declaration*/
v_total NUMBER (10);
v_inserted NUMBER (10);
v_updated NUMBER (10);
v_deleted NUMBER (10);
v_rows_inserted NUMBER (10);
v_productid PRODUCT.PRODUCTID%TYPE;
v_count NUMBER (10);
v_commit_point NUMBER := 25;
BEGIN
v_total := 0;
v_count := 0;
v_inserted := 0;
v_updated := 0;
v_deleted := 0;
v_rows_inserted := 0;
EXECUTE IMMEDIATE 'TRUNCATE TABLE VW_PRODUCT';
INSERT INTO VW_PRODUCT
SELECT * FROM Source_Product;
SELECT COUNT (*)
INTO v_rows_inserted
FROM VW_PRODUCT;
COMMIT;
/*delete data*/
FOR product_rec IN product_cursor_del
LOOP
BEGIN
v_total := v_total + 1;
update product set enddate = sysdate
WHERE productid = product_rec.productid and enddate is null;
v_deleted := v_deleted + 1;
v_count := v_count + 1;
IF (v_count >= v_commit_point)
THEN
COMMIT;
v_count := 0;
END IF;
EXCEPTION
WHEN OTHERS
THEN
BEGIN
DBMS_OUTPUT.put_line ( 'Exception with product: ' );
END;
END;
END LOOP;
FOR product_rec IN product_cursor
LOOP
BEGIN
v_total := v_total + 1;
SELECT productid
INTO v_productid
FROM product
WHERE productid = product_rec.productid;
update PRODUCT
set PACKAGEID = product_rec.PACKAGEID,
ENDDATE = product_rec.ENDDATE
WHERE PRODUCTID = product_rec.PRODUCTID;
v_updated := v_updated + 1;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
INSERT INTO PRODUCT
(PRODUCTID,PACKAGEID,ENDDATE)
VALUES
(product_rec.PRODUCTID,
product_rec.PACKAGEID,
product_rec.ENDDATE);
v_inserted := v_inserted + 1;
v_count := v_count + 1;
IF (v_count >= v_commit_point)
THEN
COMMIT;
v_count := 0;
END IF;
WHEN OTHERS
THEN
raise_application_error ('Error );
END;
END LOOP;
IF (v_total >= 1)
THEN
COMMIT;
END IF;
END;
/