假设我有一个查询,它在连接多个表后获取col1。我想在远程数据库上的表中插入该col1的值,即我将使用dblink来执行此操作。
现在col1将从4-5个不同的db中获取。有可能db2中的value1从db2中获取b。我怎样才能避免重复?
在我的远程数据库中,我已经为col1创建了一个主键。因此,在插入时,如果存在重复键,则会抛出错误,最终结果会导致进程无效。我不想这样做。我对两种方法感到兴奋
您更喜欢哪种方法?还有什么我可以做的吗?
答案 0 :(得分:2)
我会使用MERGE语句,而不是匹配然后插入。
同样的合并也可以更新但不必更新,只需将更新部分保留下来。
答案 1 :(得分:1)
首先,我建议您的目标数据库驱动所有这些插入,因为跨数据库链接插入/更新可能会产生一些锁定问题,并进一步使事情复杂化,特别是对于尝试在同一个表上访问和执行DML的多个数据库。但是,如果不可能,以下解决方案将起作用。
我会通过在每个目标表上包含一个表查找来修复主键问题。
INSERT INTO customer@dblink.oracle.com cust
(emp_name,
emp_id)
VALUES
(SELECT
cust.employee_name,
cust.employee_id --primary_key
FROM
source_table st
WHERE NOT EXISTS
(SELECT 1
FROM customer@dblink.oracle.com cust
WHERE cust.employee_id = st.emp_id));
同样,我不推荐跨数据库链接的DML事务,除非绝对必要,因为你有时会有奇怪的锁定行为。
PL / SQL过程或匿名PL / SQL块可用于创建批量处理解决方案,如下所示:
CREATE OR REPLACE PROCEDURE send_unique_data
AS
TYPE tab_cust IS TABLE OF customer@dblink.oracle.com%ROWTYPE
INDEX BY PLS_INTEGER;
t_records tab_cust;
BEGIN
SELECT
cust.employee_name,
cust.employee_id --primary_key
BULK COLLECT
INTO t_records
FROM source_table;
FORALL i IN t_records.FIRST...t_records.LAST SAVE EXCEPTIONS
INSERT INTO customer@dblink.oracle.com
VALUES t_records(i);
END send_unique_data;
如果要对引发异常的记录(例如unique_constraint违规)执行任何操作,也可以调用系统SQL%BULKEXCEPTIONS集合。请注意,如果尝试插入大量重复数据,此解决方案将导致目标表出现性能问题。