我正在尝试将全局临时表与另一个表进行比较,并想插入到日志表中,但似乎找不到最佳/最有效的方法来实现此目的。
日志表
CREATE TABLE LogTable
(
Date_Time DATETIME,
Name VARCHAR2(10 CHAR),
old VARCHAR2(20 CHAR),
new VARCHAR2(20 CHAR),
)
对象类型
CREATE OR REPLACE type dbo.P_REC AS OBJECT
(
ATTR1 VARCHAR2(10 CHAR),
ATTR2 VARCHAR2(20 CHAR),
ATTR3 VARCHAR2(20 CHAR),
ATTR4 VARCHAR2(20 CHAR)
);
集合类型
CREATE OR REPLACE type dbo.P_REC_LIST IS TABLE OF P_REC;
存储过程
PROCEDURE PASSPEOPLETOORACLE(tmpCollection IN P_REC_LIST , resultCursor out sys_refcursor)
IS
BEGIN
IF tmpCollection .count > 0 THEN
INSERT INTO tmpPTbl SELECT * FROM table1; <--tmpPTbl is a copy of table1 before the merge statement.
MERGE INTO table1 MKTP
USING (
WITH tmpTBL AS
(
SELECT ADCOLL.ATTR1,
ADCOLL.ATTR2,
MV.ATTR3,
MV.ATTR4
FROM TABLE(tmpCollection) ADCOLL
LEFT JOIN materializedView MV
ON ADCOLL.ATTR1 = MV.ATTR1
)
SELECT DISTINCT COALESCE(tmpTBL.ATTR1,MKtmpTBL.ATTR1) AS ATTR1,
tmpTBL.ATTR2,
tmpTBL.ATTR3,
tmpTBL.ATTR4,
CASE WHEN tmpTBL.ATTR1 IS NULL
THEN 'Y' ELSE 'N' END
match_flag FROM tmpTBL
FULL JOIN table1 MKtmpTBL
ON MKtmpTBL.ATTR1 = tmpTBL.ATTR1
) usingTBL
ON (MKTP.ATTR1 = usingTBL.ATTR1)
WHEN MATCHED THEN
UPDATE SET MKTP.ATTR2 = usingTBL.ATTR2,
MKTP.ATTR3 = usingTBL.ATTR3,
MKTP.ATTR4 = usingTBL.ATTR4,
DELETE WHERE match_flag = 'Y'
WHEN NOT MATCHED THEN
INSERT (ATTR1)
VALUES (usingTBL.ATTR1);
END IF;
END;
Id类似于将表1中的新更新记录与tmpPTbl中的先前记录进行比较的方法,如果新旧值不同,则在日志表中插入新行。
2019-02-14 23:59:59,jdoe,abcd,efgh
将是在日志表中插入记录的示例。
tmpPTbl和table1都有50列,平均约有1.6万行。
答案 0 :(得分:0)
最适合您的解决方案是在表Trigger
上创建一个Table1
。这样任何操作都会在Table1
上发生,因此可以将其记录到Logtable
中。参见下面的演示:
CREATE TABLE table1
(col1 VARCHAR2(10),
col2 VARCHAR2(10),
col3 VARCHAR2(10) );
/
--Trigger
CREATE OR REPLACE TRIGGER Log_Entry before
INSERT OR
UPDATE ON table1 FOR EACH row
BEGIN
IF INSERTING THEN
INSERT INTO LogTable VALUES
(sysdate, :new.col1, :new.col2, :new.col3
);
ELSIF UPDATING THEN
INSERT INTO LogTable VALUES
(sysdate, :old.col1, :old.col2, :old.col3
);
END IF;
END;
/
执行:
SQL> Insert into table1 values ('A','B','C');
SQL>Update table1
set col1 ='Z'
where col1 = 'A';
SQL> Merge INTO table1 tb1 USING
(SELECT 'Z' col1 , 'D' col2, 'K' col3 FROM dual
) tb2 ON (tb1.col1 = tb2.col1)
WHEN matched THEN
UPDATE SET tb1.col2=tb2.col2 WHEN NOT matched THEN
INSERT VALUES
(tb2.col1,tb2.col2,tb2.col3
);
SQL>Commit;
SQL> Select * from logtable;
DATE_TIME NAME OLD NEW
--------- ---------- -------------------- --------------------
15-FEB-19 A B C
15-FEB-19 Z B C
15-FEB-19 Z B C
请注意,也无需将数据复制到tmpPTbl
表中。