对于批量加载导入的数据,我进行了一些处理,并将该处理的结果存储在临时表中。然后,我可以使用分阶段数据将更改应用于其他表。
当导入的数据正确时,这非常有效,但有时可能包含错误,例如对未使用的外键的引用或主键的重复。
我想实现类似下面的示例(当数据没有错误时有效),但而不是失败整个操作,我想记录冲突行并继续处理。
假设我有一个items
表和一个items_operations
临时表。然后,在填充items_operations
之后,我可以......
制作新商品
INSERT INTO items (id, name, manufacturer_id, price)
SELECT
item_id,
item_name,
item_manufacturer_id
item_price
FROM items_operations
WHERE operation = 'creation'
(如果id
存在重复的manufactuer_id
或不存在的FK,则可能会失败
更新现有项目
UPDATE items t1
SET (name, manufacturer_id, price) =
(SELECT
t2.item_name,
t2.item_manufacturer_id,
t2.item_price
FROM items_operations t2
WHERE t1.id = t2.item_id
AND t2.operation = 'modification')
WHERE EXISTS (
SELECT 1
FROM items_operations t2
WHERE t1.id = t2.item_id
AND t2.operation = 'modification')
(对于manufacturer_id
items
表真的很大(约300MM记录)可能很重要,因此应该避免不必要的连接。items_operations
包含对未存在项目的更新(id
上没有匹配items
的{{1}})。这不会失败,但如果我能够记录那些不匹配的项目,那将是理想的。答案 0 :(得分:2)
听起来你想使用DML error logging
创建错误表(每个要加载的表一次)
begin
dbms_errlog.create_error_log( dml_table_name => 'ITEMS' );
end;
/
然后您可以使用LOG ERRORS INTO
子句
INSERT INTO items (id, name, manufacturer_id, price)
SELECT
item_id,
item_name,
item_manufacturer_id
item_price
FROM items_operations
WHERE operation = 'creation'
LOG ERRORS INTO err$_items
REJECT LIMIT UNLIMITED;
然后,您可以查询err$_items
以查看引发的错误。
对于非失败的事物(即item_operations
中items
中没有匹配行的项目),您需要运行查询才能找到它们。接下来,我将定义一个外键约束,阻止您在不存在的项上记录操作。