我有以下脚本来通过读取远程源表来更新本地表。脚本运行正常,没有任何错误。这篇文章是为了正确阐明光标的工作原理。
我从远程源表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;
/
答案 0 :(得分:0)
简而言之,要回答您的基本问题,
FETCH语句执行以下操作: