首先,我建议您的目标数据库驱动所有这些插入,因为跨数据库链接插入/更新可能会产生一些锁定问题并使事情进一步复杂化,尤其是在多个数据库尝试访问并在同一个表上执行 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;
您还可以调用系统 SQL%BULKEXCEPTIONS 集合,以防您想对引发异常的记录(例如违反 unique_constraint)做任何事情。请注意,如果尝试插入大量重复数据,此解决方案将导致目标表出现性能问题。