【问题标题】:Oracle Loop Rule 4809Oracle 循环规则 4809
【发布时间】:2019-06-10 13:33:20
【问题描述】:

我需要编写一个在表中插入数千行的过程,并使用这些行生成的自动生成的 id 并将其用于其他插入。

我使用了一个 for 循环,其中我将序列 id 保存在一个变量中,然后在我的插入中使用它。

declare
first_id integer;
BEGIN
FOR texts in (select distinct text from table_texts  )
 LOOP
first_id := SEQ_IDS_OBJECTID.NEXTVAL;
INSERT INTO  table_1(id,some_fields)
VALUES (first_id, 'blablabla');

insert into table_2 (id,text_field)
 VALUES (first_id, texts.text);
END LOOP;
commit;
 END;

我认为这不是实现我需要的理想方式。此外,当我在 TOAD 中输入代码时,我收到以下警告: 规则 4809(包含 DML 语句的循环应重构为使用 BULK COLLECT 和 FORALL)

有没有更好的办法?

编辑:

上面的代码被简化了。但我想我必须揭露更多来解释这个案子:

declare
first_id  integer;
second_id integer;

BEGIN


FOR texts in (select distinct text1 , text2  from mdf )

LOOP

first_id := XAKTA.SEQ_IDS_OBJECTID.NEXTVAL;

select id_1 into second_id from table_3 where  field_1 =texts.text1 ;

INSERT INTO  table_1(id_1,id_2,some_fields)
VALUES (first_id ,second_id ,'blablabla');

insert into table_2 (id,text1,text2)
 VALUES (first_id, texts.text1,texts.text2);

END LOOP;    
commit;
 END;

【问题讨论】:

    标签: oracle plsql


    【解决方案1】:

    您可以使用FORALL 从光标处插入一批项目:

    DECLARE
      TYPE texts_tab IS TABLE OF table_texts.text%TYPE;
      TYPE ids_tab   IS TABLE OF table_2.id%TYPE;
      p_texts texts_tab;
      p_ids   ids_tab;
      CURSOR c IS
        SELECT DISTINCT text FROM table_texts;
    BEGIN
      OPEN c;
      LOOP
        FETCH c BULK COLLECT INTO p_texts LIMIT 100;
    
        FORALL i IN 1 .. p_texts.COUNT
          INSERT INTO table_2 ( id, text_field )
                       VALUES ( SEQ_IDS_OBJECTID.NEXTVAL, p_texts(i) )
          RETURNING id BULK COLLECT INTO p_ids;
    
        FORALL i IN 1 .. p_ids.COUNT
          INSERT INTO  table_1( id, some_fields )
            VALUES ( p_ids(i), 'blablabla' );
    
        EXIT WHEN c%NOTFOUND;
      END LOOP;
      CLOSE c;
      COMMIT;
    END;
    /
    

    db小提琴here

    【讨论】:

    • 谢谢!如果 table_texts 表包含两个字段怎么办:SELECT DISTINCT text1,text2 FROM table_texts;其中 text1 和 text2 都将被使用。在这种情况下会发生什么变化?
    • 我用更真实的代码编辑了帖子。你能检查一下吗?
    猜你喜欢
    • 1970-01-01
    • 2014-08-29
    • 2013-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多