考虑一下这个表:
表:ORDER 列:id,order_num,order_date,order_status
此表有100万条记录。我想将order_status更新为'5'的值,对于我将从输入文本文件中读取的一堆(大约10,000)order_num。
My SQL could be:
(A) update ORDER set order_status=5 where order_num in ('34343', '34454', '454545',...)
OR
(B) update ORDER set order_status=5 where order_num='34343'
我可以多次循环此更新,直到我完成10,000次订单更新。 (另请注意,我有很少的ORDER子表,如ORDER_ITEMS,其中必须更新类似状态并审核信息)
我的问题是:
如何在单独的ORDER_AUDIT表中审核此更新:
Order_Num:34343 - 成功更新
Order_Num:34454 - 未找到订单
Order_Num:454545 - 成功更新
Order_Num:45457 - 订单未找到
如果按照(A)进行批量更新,我无法在订单级别进行审核 如果我按照(B)中的时间更新单一订单,我将需要循环10,000次 - 这可能相当慢 - 但在这种情况下我可以在订单级审核。
还有其他办法吗?
答案 0 :(得分:1)
首先,在“输入文本文件”上构建一个外部表。这样你就可以运行一个简单的UPDATE语句:
update ORDER
set order_status=5
where order_num in ( select col1 from ext_table order by col1)
整洁有效。 (对子查询进行排序是可选的:它可以提高更新的性能,但关键是,我们可以像处理常规表一样处理外部表,并使用完整的SELECT语法。)Find out more。
其次使用RETURNING子句捕获命中。
update ORDER
set order_status=5
where order_num in ( select col1 from ext_table order by col1)
returning order_num bulk collect into l_nums;
此上下文中的 l_nums
是类型编号的PL / SQL集合。 RETURNING子句将仅为更新的行提供所有ORDER_NUM值。 Find out more。
如果您将l_nums
的类型声明为a SQL nested table object,则可以在其他SQL语句中将其用于审核:
insert into order_audit
select 'Order_Num: '||to_char(t.column_value)||' - Updated Succesfully'
from table ( l_nums ) t
/
insert into order_audit
select 'Order_Num: '||to_char(col1)||' - Order Not Found'
from ext_table
minus
select * from table ( l_nums )
/
绩效说明:
您没有说输入文本文件中有多少行匹配。也许你不知道(实际上重新阅读它不清楚10,000是文件中的行数还是匹配的行数)。 Pl / SQL集合使用私有会话内存,因此非常大的集合可以破坏PGA。但是,您应该能够处理一万个NUMBER个实例而不会蒙羞。
我的解决方案确实需要您两次读取外部表。这应该不是问题。它肯定会方式更快比动态组装一千个数字的一百个IN子句并循环遍历各个数字。
请注意,更新通常是人类已知的最慢的批量操作。有一些方法可以加速它们,但这些方法可以非常复杂。但是,如果这是你经常想要做的事情而性能成为一个棘手的问题你应该read this OraFAQ article。
答案 1 :(得分:0)
使用MERGE。首先将数据加载到名为ORDER_UPD_TMP的临时表中,只有一个列id。您可以使用SQLDeveloper导入功能来完成此操作。然后使用MERGE来更新基表:
MERGE INTO ORDER b
USING (
SELECT order_id
FROM ORDER_UPD_TMP
) e
ON (b.id = e.id)
WHEN MATCHED THEN
UPDATE SET b.status = 5
当记录不匹配时,您还可以使用其他状态进行更新。查看文档以获取更多详细信息:
http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9016.htm
答案 2 :(得分:-1)
我认为最好的方法是:
status
并创建审计记录。