修改存储过程以忽略重复记录

时间:2017-10-31 13:47:35

标签: oracle stored-procedures plsql primary-key

我需要对此存储过程进行以下修改

create or replace PROCEDURE                 "USP_IMPORT_FOBTPP_DATA" 
AS
BEGIN
INSERT INTO FINIMP.FOBT_PARTPAYMENT
SELECT
PART_PAYMENT_ID,
ISSUING_SHOP,
TILL_NUMBER,
SLIP_NUMBER,
FOBT_NUMBER,
WHO_PAID,
WHEN_PAID,
AMOUNT_LEFT_TO_PAY,
FOBT_VALUE,
STATUS
FROM IMPORTDB.CLN_FOBTPP;

COMMIT;
END;

为了跳过任何会导致主键违规的记录,这样就不会破坏dataload进程。

Source Table
CREATE TABLE "FINIMP"."FOBT_PARTPAYMENT" 
(   "PART_PAYMENT_ID" NUMBER(*,0), 
"ISSUING_SHOP" CHAR(4 BYTE), 
"TILL_NUMBER" NUMBER(3,0), 
"SLIP_NUMBER" NUMBER(*,0), 
"FOBT_NUMBER" VARCHAR2(30 BYTE), 
"WHO_PAID" CHAR(20 BYTE), 
"WHEN_PAID" DATE, 
"AMOUNT_LEFT_TO_PAY" NUMBER(19,4), 
"FOBT_VALUE" NUMBER(19,4), 
"STATUS" CHAR(2 BYTE)
);

ALTER TABLE "FINIMP"."FOBT_PARTPAYMENT" ADD CONSTRAINT "PK_FOBT_PP" PRIMARY KEY ("PART_PAYMENT_ID", "ISSUING_SHOP", "WHEN_PAID")

我是PL / SQL的新手,我该怎么做?

1 个答案:

答案 0 :(得分:0)

有很多方法可以实现这一点,最好的方法取决于您的环境/要求。 CLN_FOBTPP表格相当大吗? USP_IMPORT_FOBTPP_DATA过程是否经常被调用,是否需要满足某些性能标准?这些都是你应该考虑的事情。

执行此操作的一种方法是从您使用的查询开始。

create or replace PROCEDURE "USP_IMPORT_FOBTPP_DATA" 
AS
BEGIN
INSERT INTO FINIMP.FOBT_PARTPAYMENT
SELECT ...
FROM IMPORTDB.CLN_FOBTPP;

这将返回IMPORTDB.CLN_FOBTP的所有数据行,并将其插入FINIMP.FOBT_PARTPAYMENT。相反,您可以通过执行以下操作来控制:

INSERT INTO FINIMP.FOBT_PARTPAYMENT
SELECT ...
FROM IMPORTDB.CLN_FOBTPP WHERE PART_PAYMENT_ID NOT IN (FINIMP.FOBT_PARTPAYMENT)

这将通过FOBT_PARTPAYMENT表,并在执行插入之前检查表中是否存在行PART_PAYMENT_ID。但是,如果桌子很大或者你有性能要求,这可能会非常昂贵。

另一种方法是每次调用过程时创建一个临时表,将值存储在该临时表中,然后在验证数据后添加新行。这看起来像是:

create global temporary table temp_USP_table ("PART_PAYMENT_ID" NUMBER(*,0), "ISSUING_SHOP" CHAR(4 BYTE),...) on commit delete rows;
create or replace PROCEDURE "USP_IMPORT_FOBTPP_DATA" 
AS
BEGIN
INSERT INTO temp_USP_table
SELECT ...
FROM IMPORTDB.CLN_FOBTPP;

从那里,你可以做很多事情。您可以使用相同的过程将临时表中的新行添加到FINIMP.FOBT_PARTPAYMENT表中:

delete from temp_USP_table where PART_PAYMENT_ID in FINIMP.FOBT_PARTPAYMENT;
insert into FINIMP.FOBT_PARTPAYMENT select * from temp_USP_table;

或者您可以创建一个新程序,将temp_USP_table中的新数据加载到FINIMP.FOBT_PARTPAYMENT表中,以防您想要在新数据之前执行其他操作&# 39; s添加到表中。由于您引用了数据加载,我建议您使用临时表路由,因为它应该允许您加载数据而不会出现问题。加载数据后,您可以担心将其添加到正确的表中。