Plsql 我需要在这里使用什么?另一个光标,一条记录还是别的什么?

Plsql 我需要在这里使用什么?另一个光标,一条记录还是别的什么?,plsql,oracle11g,Plsql,Oracle11g,下面的代码是我昨天问题的答案,具有ff结果: 首轮 更新:0 插入:4 第二轮 更新:4 插入:0 删除cid“1”和“3”后: 更新:2 插入:2 我现在想要的是在不使用嵌套块的情况下修改此代码。也许是这样的: DECLARE ins NUMBER := 0; upd NUMBER := 0; CURSOR c1 IS SELECT cid FROM tbl_cust

下面的代码是我昨天问题的答案,具有ff结果:

首轮

更新:0
插入:4
第二轮

更新:4
插入:0
删除cid“1”和“3”后:

更新:2
插入:2
我现在想要的是在不使用嵌套块的情况下修改此代码。也许是这样的:

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)

然而,如果你坚持你的逻辑,那么你应该使用某种集合。(看这里)

然而,您不能将异常处理放在循环外部,它仍然应该在循环内部

下面是它的样子:

 DECLARE
        ins NUMBER := 0;
        upd NUMBER := 0;
        CURSOR c1 IS
            SELECT cid
            FROM tbl_cust
            WHERE cid 
            IN ('1','2','3','4');
        --declare something as 'holder of values' 
        TYPE list_of_ids IS TABLE OF number;
        duplicates list_of_ids:= list_of_ids (); 
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 + sql%rowcount;
        EXCEPTION   WHEN DUP_VAL_ON_INDEX THEN
        duplicates.EXTEND;
        duplicates(duplicates.LAST):=rec.cid;
        end; 
       --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);  


      --a loop here to update values in the 'holder of values'
      FOR l_row IN 1 .. duplicates.COUNT
      LOOP
         UPDATE tbl2 set name_tbl2 = DECODE(duplicates (l_row), '1', 'A',
                                        '2', 'B',
                                        '3', 'C',
                                        '4', 'D')
        WHERE cust_cust_code := duplicates (l_row);
        upd := upd + sql%rowcount; 
         DBMS_OUTPUT.put_line (duplicates (l_row));
      END LOOP;

    dbms_output.put_line('Updated: ' || upd);
    dbms_output.put_line('Inserted: ' || ins);
END;

我认为您应该使用中@APC建议的
合并到
。语法对您来说可能是新的,但值得理解。我无法理解你在这个问题上对所有循环的期望。我已经尝试了通过@APC合并到中,这也是解决这个问题的一个好方法,但我想知道的是一种按照我的想法修改代码的方法。是的,因为为什么要用简单明了的方式编写解决方案,当我们可以花更多的时间写一段缓慢、难以理解的代码时,表现时尚?老兄,再次感谢你的回答。使用collection给了我一个如何做的想法。@SurfacetExtension OK没问题;-)顺便说一句——如果答案有帮助的话——至少,放弃投票吧。。。
 DECLARE
        ins NUMBER := 0;
        upd NUMBER := 0;
        CURSOR c1 IS
            SELECT cid
            FROM tbl_cust
            WHERE cid 
            IN ('1','2','3','4');
        --declare something as 'holder of values' 
        TYPE list_of_ids IS TABLE OF number;
        duplicates list_of_ids:= list_of_ids (); 
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 + sql%rowcount;
        EXCEPTION   WHEN DUP_VAL_ON_INDEX THEN
        duplicates.EXTEND;
        duplicates(duplicates.LAST):=rec.cid;
        end; 
       --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);  


      --a loop here to update values in the 'holder of values'
      FOR l_row IN 1 .. duplicates.COUNT
      LOOP
         UPDATE tbl2 set name_tbl2 = DECODE(duplicates (l_row), '1', 'A',
                                        '2', 'B',
                                        '3', 'C',
                                        '4', 'D')
        WHERE cust_cust_code := duplicates (l_row);
        upd := upd + sql%rowcount; 
         DBMS_OUTPUT.put_line (duplicates (l_row));
      END LOOP;

    dbms_output.put_line('Updated: ' || upd);
    dbms_output.put_line('Inserted: ' || ins);
END;