Oracle 循环规则 4809
Posted
技术标签:
【中文标题】Oracle 循环规则 4809【英文标题】:Oracle Loop Rule 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;
【问题讨论】:
【参考方案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 都将被使用。在这种情况下会发生什么变化? 我用更真实的代码编辑了帖子。你能检查一下吗?以上是关于Oracle 循环规则 4809的主要内容,如果未能解决你的问题,请参考以下文章
drools规则引擎中易混淆语法分析_循环触发导致死循环分析