oracle – 在plsql中使用for循环更新
|
我有更新问题并插入下面的列.请告知此事. 这是输入 depnto extra comm ---------------------------- 20 300 NULL 20 300 400 20 NULL NULL 20 500 NULL 这是预期的产出 depnto Extra comm --------------------- 20 300 300 20 300 400 20 NULL NULL 20 500 500 我需要在以下条件下使用额外列更新comm列. >如果comm为null,则将额外值更新为comm. 我的节目如下.即使我需要跟踪哪些行已更新以及哪个值在另一个表中. PROCEDURE (dept_id )
AS
BEGIN
FOR r IN (SELECT *
FROM emp
WHERE comm IS NULL AND extra IS NOT NULL AND deptno = dept_id)
LOOP
UPDATE emp
SET comm = extra
WHERE comm IS NULL AND extra IS NOT NULL AND deptno = dept_id;
INSERT INTO changed_comm (deptno,oldval,newval)
VALUES (dept_id,r.comm,r.extra);
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
NULL;
END;
请在上面提供一些意见.它没有正确插入. 解决方法你不需要FOR LOOP,只需要一个UPDATE即可完成工作:UPDATE emp SET comm = extra WHERE comm IS NULL AND extra IS NOT NULL; 这是一个演示:http://www.sqlfiddle.com/#!4/aacc3/1 —编辑—- UPDATE emp SET deptno = 20 WHERE deptno = 10; —-编辑—– CREATE OR REPLACE PROCEDURE pro_cedure( p_dept_id number )
IS
TYPE changed_table_type IS TABLE OF changed%ROWTYPE;
changed_buff changed_table_type;
BEGIN
SELECT deptno,comm,extra BULK COLLECT INTO changed_buff
FROM emp
WHERE comm IS NULL AND extra IS NOT NULL AND deptno = p_dept_id
FOR UPDATE;
UPDATE emp
SET comm = extra
WHERE comm IS NULL AND extra IS NOT NULL AND deptno = p_dept_id;
FORALL i IN 1 .. changed_buff.count
INSERT INTO changed VALUES changed_buff( i );
END;
/
如果您不打算在一次调用中处理大量记录(超过1000 …或最多几千),则该过程应该有效.如果一个dept_id可以包含一万或更多行,那么这个过程可能会很慢,因为它会消耗大量的PGA内存.在这种情况下,需要另一种以块的形式进行批量收集的方法. – 编辑—如何存储序列值——- 我假设更改的表有4列,如下所示: CREATE TABLE "TEST"."CHANGED" ( "DEPTNO" NUMBER,"OLDVAL" NUMBER,"NEWVAL" NUMBER,"SEQ_NEXTVAL" NUMBER ) ; 我们将序列值存储在seq_nextval列中. 在这种情况下,过程可能如下所示: create or replace
PROCEDURE pro_cedure( p_dept_id number )
IS
TYPE changed_table_type IS TABLE OF changed%ROWTYPE;
changed_buff changed_table_type;
BEGIN
SELECT deptno,extra,sequence_name.nextval
BULK COLLECT INTO changed_buff
FROM emp
WHERE comm IS NULL AND extra IS NOT NULL AND deptno = p_dept_id
FOR UPDATE;
UPDATE emp
SET comm = extra
WHERE comm IS NULL AND extra IS NOT NULL AND deptno = p_dept_id;
FORALL i IN 1 .. changed_buff.count
INSERT INTO changed VALUES changed_buff( i );
END;
—编辑—带光标的版本用于小数据集—– 是的,对于小型数据集批量收集不会显着提高速度,并且在这种情况下使用for..loop的普通光标就足够了. create or replace
PROCEDURE pro_cedure( p_dept_id number )
IS
CURSOR mycursor IS
SELECT deptno,extra
FROM emp
WHERE comm IS NULL AND extra IS NOT NULL
AND deptno = p_dept_id
FOR UPDATE;
BEGIN
FOR emp_rec IN mycursor
LOOP
UPDATE emp
SET comm = extra
WHERE CURRENT OF mycursor;
INSERT INTO changed( deptno,newval,seq_nextval)
VALUES( emp_rec.deptno,emp_rec.comm,emp_rec.extra,sequence_name.nextval );
END LOOP;
END;
(编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


