Oracle Loop规则4809

时间:2019-06-10 13:33:20

标签: oracle plsql

我需要编写一个过程,该过程将在表中插入数千行,并使用这些行产生的自动生成的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;

1 个答案:

答案 0 :(得分:0)

您可以使用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