这是我正在尝试做的事情:
1)在临时表中插入原始表中的一些值
INSERT INTO temp_table SELECT id FROM original WHERE status='t'
2)更新原始表
UPDATE original SET valid='t' WHERE status='t'
3)根据两个表之间的连接选择
SELECT * FROM original WHERE temp_table.id = original.id
有没有办法合并第1步和第2步?
答案 0 :(得分:5)
您可以通过在PL / SQL中执行更新并使用RETURNING子句将更新的ID导入PL / SQL表来组合这些步骤。
修改强>
如果仍然需要进行最终查询,仍然可以使用此方法插入temp_table;虽然取决于最后一个查询的用途,但可能还有其他方法可以实现您的目标。举例说明:
DECLARE
id_table_t IS TABLE OF original.id%TYPE INDEX BY PLS_INTEGER;
id_table id_table_t;
BEGIN
UPDATE original SET valid='t' WHERE status='t'
RETURNING id INTO id_table;
FORALL i IN 1..id_table.COUNT
INSERT INTO temp_table
VALUES (id_table(i));
END;
/
SELECT * FROM original WHERE temp_table.id = original.id;
答案 1 :(得分:3)
答案 2 :(得分:0)
在插入temp_table并更新原始文件后,可能会创建一个TRIGGER。
答案 3 :(得分:0)
创建一个光标,保存insert中的值,然后循环更新表格。首先不需要创建临时表。
答案 4 :(得分:0)
您可以使用MERGE语句和DML错误日志记录组合步骤1和2。选择两倍的行,更新其中的一半,并强制另一半失败,然后插入到可用作临时表的错误日志中。
下面的解决方案假设您对ID有主键约束,但还有其他方法可以强制失败。
虽然我认为这很酷,但我建议你不要使用它。它看起来很奇怪,有一些奇怪的问题(TEMP_TABLE中的插入是自动提交的),并且可能非常慢。
--Create ORIGINAL table for testing.
--Primary key will be intentionally violated later.
create table original (id number, status varchar2(10), valid varchar2(10)
,primary key (id));
--Create TEMP_TABLE as error log. There will be some extra columns generated.
begin
dbms_errlog.create_error_log(dml_table_name => 'ORIGINAL'
,err_log_table_name => 'TEMP_TABLE');
end;
/
--Test data
insert into original values(1, 't', null);
insert into original values(2, 't', null);
insert into original values(3, 's', null);
commit;
--Update rows in ORIGINAL and also insert those updated rows to TEMP_TABLE.
merge into original original1
using
(
--Duplicate the rows. Only choose rows with the relevant status.
select id, status, valid, rownumber
from original
cross join
(select 1 rownumber from dual union all select 2 rownumber from dual)
where status = 't'
) original2
on (original1.id = original2.id and original2.rownumber = 1)
--Only math half the rows, those with rownumber = 1.
when matched then update set valid = 't'
--The other half will be inserted. Inserting ID causes a PK error and will
--insert the data into the error table, TEMP_TABLE.
when not matched then insert(original1.id, original1.status, original1.valid)
values(original2.id, original2.status, original2.valid)
log errors into temp_table reject limit 999999999;
--Expected: ORIGINAL rows 1 and 2 have VALID = 't'.
--TEMP_TABLE has the two original values for ID 1 and 2.
select * from original;
select * from temp_table;