您好我正在使用以下PLSQL脚本在新表new_table中插入行。
set serveroutput on SIZE 1000000;
DECLARE
CURSOR get_record IS
SELECT * from cycle_table ;
BEGIN
FOR rec IN get_record
LOOP
DBMS_OUTPUT.put_line('Inserting Record into new_table..');
EXECUTE IMMEDIATE('insert into new_table
select cycle_code,cycle_instance,cycle_start_date,cycle_end_date
from cycle_table');
END LOOP;
COMMIT;
END;
/
现在表cycle_table只包含4行。循环只运行四次,因为它的打印'将记录插入new_table ..'仅4次。
但是当我看到new_table时,它包含16行。这意味着每次循环迭代它都插入所有4行,因此总共16行。
我想要的是它一次插入一行。 这样我也可以在那一行上执行其他操作。就像行已经存在一样,插入一些其他表或任何东西。
请建议我该怎么办?我在oracle 10g上使用SQL开发人员
提前致谢
答案 0 :(得分:1)
这很简单:
set serveroutput on SIZE 1000000;
DECLARE
BEGIN
FOR rec in (select * from cycle_table)
LOOP
DBMS_OUTPUT.put_line('Inserting Record into new_table..');
insert into new_table (cycle_code,
cycle_instance,
cycle_start_date,
cycle_end_date)
values (rec.cycle_code,
rec.cycle_instance,
rec.cycle_start_date,
rec.cycle_end_date);
END LOOP;
COMMIT;
END;
/
但是,我会劝阻这种方法,因为如果有大量记录,你可能会遇到性能问题。你只有四个,所以很好。
我反对这一点的原因是Oracle的PL / SQL引擎和SQL引擎之间存在上下文切换。我建议您执行insert into .... select...
或使用forall
,因为这些资源消耗最少。
答案 1 :(得分:0)
更有效的方法是消除所有循环,并允许SQL处理所有内容。这是我的建议:
BEGIN
-- Handle matches first, because after you handle non-matches, everything matches
INSERT INTO match_table (cycle_code, cycle_instance, cycle_start_date
, cycle_end_date)
SELECT cycle_table.cycle_code, cycle_table.cycle_instance, cycle_table.cycle_start_date
, cycle_table.cycle_end_date
FROM cycle_table INNER JOIN new_table ON (new_table.cycle_code = cycle_table.cycle_code);
-- Single insert to insert all non matching records
INSERT INTO new_table (cycle_code, cycle_instance, cycle_start_date
, cycle_end_date)
SELECT cycle_code, cycle_instance, cycle_start_date
, cycle_end_date
FROM cycle_table
WHERE NOT EXISTS
(SELECT NULL
FROM new_table
WHERE new_table.cycle_code = cycle_table.cycle_code);
COMMIT;
END;