oracle - 使用合并在 Oracle 触发器中实现类型 II SCD
问题描述
对于我的生活,我无法让以下查询工作......基本上它是对以下票证的修改: 在 oracle 中使用 Merge 语句触发。
CREATE OR REPLACE TRIGGER TABLE_UPDATE
AFTER INSERT OR UPDATE ON DIM_TABLE
FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF INSERTING OR UPDATING
THEN
MERGE INTO DIM_TABLE T_1
USING( SELECT COL_1, max(VALID_FROM) AS LAST_DATE FROM
DIM_TABLE
GROUP BY COL_1) T_2
ON (T_1. COL_1= T_2. COL_1)
WHEN NOT MATCHED THEN INSERT (T_1. VALID_FROM) VALUES(SYSDATE)
WHEN MATCHED THEN
UPDATE
SET T_1.VALID_UNTIL = T_2.LAST_DATE
WHERE T_1. VALID_UNTIL is null
AND T_1. VALID_FROM <> T_2.LAST_DATE;
COMMIT;
END IF;
END;
所需功能:将一个值输入数据库 (COL_1)。如果该列没有匹配项,则将 VALID_FROM 日期输入为 sysdate。如果匹配,则脚本应更新前一行的 VALID_UNTIL 值(直到现在它仍为空,因为它仍然有效)。
我不断收到以下错误:死锁和最大递归级别超出(50)
解决方案
I really struggle getting your requirement. To me it seems that you want VALID_FROM
to be either sysdate
or the max value for each COL_1
.
That I would do by making use of :NEW
to manipulate current row
set linesize 250
drop table dim_Table;
create table dim_table (col_1 varchar2(50), valid_from timestamp);
CREATE OR REPLACE TRIGGER TABLE_UPDATE
before INSERT OR UPDATE ON DIM_TABLE
FOR EACH ROW
DECLARE
l_valid_from date;
BEGIN
select max(valid_from)
into l_valid_from
from dim_table t1
where t1.col_1 = :new.col_1;
if l_valid_from is null then
:new.valid_from := sysdate;
else
:new.valid_from := l_valid_from;
end if;
END;
insert into dim_table (col_1) values ('TEST1');
select * from dim_table;
exec dbms_lock.sleep(1);
insert into dim_table (col_1) values ('TEST1');
select * from dim_table;
exec dbms_lock.sleep(1);
insert into dim_table (col_1) values ('TEST2');
select * from dim_table;
exec dbms_lock.sleep(1);
insert into dim_table (col_1) values ('TEST1');
select * from dim_table;
exec dbms_lock.sleep(1);
insert into dim_table (col_1) values ('TEST2');
select * from dim_table;
Output:
Table dropped.
Table created.
Trigger created.
1 row created.
COL_1 VALID_FROM
-------------------------------------------------- --------------------------------------------------
TEST1 30/04/2019 09:13:10.000000
1 row selected.
PL/SQL procedure successfully completed.
1 row created.
COL_1 VALID_FROM
-------------------------------------------------- --------------------------------------------------
TEST1 30/04/2019 09:13:10.000000
TEST1 30/04/2019 09:13:10.000000
2 rows selected.
PL/SQL procedure successfully completed.
1 row created.
COL_1 VALID_FROM
-------------------------------------------------- --------------------------------------------------
TEST1 30/04/2019 09:13:10.000000
TEST1 30/04/2019 09:13:10.000000
TEST2 30/04/2019 09:13:12.000000
3 rows selected.
PL/SQL procedure successfully completed.
1 row created.
COL_1 VALID_FROM
-------------------------------------------------- --------------------------------------------------
TEST1 30/04/2019 09:13:10.000000
TEST1 30/04/2019 09:13:10.000000
TEST2 30/04/2019 09:13:12.000000
TEST1 30/04/2019 09:13:10.000000
4 rows selected.
PL/SQL procedure successfully completed.
1 row created.
COL_1 VALID_FROM
-------------------------------------------------- --------------------------------------------------
TEST1 30/04/2019 09:13:10.000000
TEST1 30/04/2019 09:13:10.000000
TEST2 30/04/2019 09:13:12.000000
TEST1 30/04/2019 09:13:10.000000
TEST2 30/04/2019 09:13:12.000000
5 rows selected.
推荐阅读
- java - 从 Java 访问 Kotlin 枚举
- ios - 在我的 iOS 应用程序中包含 HTTP(不是 HTTPS)URL 链接,我是否需要禁用应用程序传输安全性?
- c# - 将 Base64 转换为字符串会插入空格
- python - 如何使用python禁用windows上的printscreen键
- python - 如何提取 HDF5 数组矩阵的一部分及其对应的行属性
- firebase - Firebase Cloud Firestore 的成本优化模式:通过集合获取文档
- javascript - 每 3-4 个字符插入空格
- css - 设置背景混合模式和背景颜色在 HTML 电子邮件中不起作用
- angular - Chrome 开发工具不会显示所有源文件。这是正常的还是错误的?
- php - WooCommerce 类别页面上的自定义页面标题和描述