【发布时间】:2018-02-09 14:50:11
【问题描述】:
下面的代码是我昨天的问题的答案,结果是 ff:
第一次运行
Updated: 0
Inserted: 4
第二次运行
Updated: 4
Inserted: 0
删除 cid '1' 和 '3' 后:
Updated: 2
Inserted: 2
DECLARE
ins NUMBER := 0;
upd NUMBER := 0;
CURSOR c1 IS
SELECT cid
FROM tbl_cust
WHERE cid
IN ('1','2','3','4');
BEGIN
FOR rec IN c1 LOOP
begin
INSERT INTO tbl2 (id_tbl2, name_tbl2)
VALUES(rec.cid, DECODE(rec.cid, '1', 'A',
'2', 'B',
'3', 'C',
'4', 'D'));
ins := ins + 1;
EXCEPTION WHEN DUP_VAL_ON_INDEX THEN
UPDATE tbl2 set name_tbl2 = DECODE(rec.cid, '1', 'A',
'2', 'B',
'3', 'C',
'4', 'D'));
WHERE cust_cust_code = rec.cid;
upd := upd + 1;
continue;
end;
END LOOP;
dbms_output.put_line('Updated: ' || upd);
dbms_output.put_line('Inserted: ' || ins);
END;
我现在想要的是在不使用嵌套块的情况下修改这段代码。也许是这样的:
DECLARE
ins NUMBER := 0;
upd NUMBER := 0;
CURSOR c1 IS
SELECT cid
FROM tbl_cust
WHERE cid
IN ('1','2','3','4');
--maybe declare something as 'holder of values' which are ducplicates and cannot be inserted then will be used on a condition or loop to update.
BEGIN
FOR rec IN c1 LOOP
INSERT INTO tbl2 (id_tbl2, name_tbl2)
VALUES(rec.cid, DECODE(rec.cid, '1', 'A',
'2', 'B',
'3', 'C',
'4', 'D'));
ins := ins + 1;
--maybe put some condition here to pass the values that are not insert to the 'holder of values'
END LOOP;
dbms_output.put_line('Updated: ' || upd);
dbms_output.put_line('Inserted: ' || ins);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
--maybe put a loop here to update values in the 'holder of values'
UPDATE tbl2 set name_tbl2 = DECODE('holder of values'.VALUE, '1', 'A',
'2', 'B',
'3', 'C',
'4', 'D')
WHERE cust_cust_code = 'holder of values'.VALUE;
upd := upd + 1;
dbms_output.put_line('Updated: ' || upd);
dbms_output.put_line('Inserted: ' || ins);
END;
【问题讨论】:
-
我认为您应该按照@APC 在stackoverflow.com/a/48679336/7998591 中的建议使用
MERGE INTO。语法对您来说可能是新的,但值得理解。对于所有循环,我无法弄清楚您在这个问题中的期望。 -
我已经尝试通过@APC 进行合并,这也是解决此问题的好方法,但我想知道的是一种按照我的想法修改代码的方法。
-
是的,因为当我们可以花更多时间编写缓慢、难以理解的代码块时,为什么还要以简单、高效的方式编写解决方案?