我有一个源表,其中包含字段 ID
NAME
和 DESIG
create or replace table emp_source
(
id number,
name string,
desig string
);
我的目标表有列ID
NAME
DESIG
META_CRT_DT
(插入记录的日期)META_UPD_DT
(更新记录的日期)META_IUD_FLG
(根据执行的插入、删除或更新操作进行更新)CURRENT_FLAG
(如果记录被删除,我必须让这个错误)
create or replace table emp_des
(
id number,
name string,
desig string,
META_CRT_DT timestamp_ntz,
META_UPD_DT timestamp_ntz,
META_IUD_FLG char,
current_flag boolean
);
我正在像这样插入新记录
INSERT INTO emp_des (id, name, desig,META_CRT_DT,
meta_upd_dt, meta_iud_flg, current_flag)
SELECT
id, name, desig,
to_date(current_timestamp) as crt,
to_date(current_timestamp) as upd,
'I' as iud, TRUE as flag
FROM
emp_source
WHERE
NOT EXISTS (SELECT * FROM emp_des
WHERE emp_source.id = emp_des.id);
当源表中的记录更新时,假设名称发生更改,在 EMP_DES
表中我需要更新 DESIG
、META_UPD_DT
> 和 META_IUD_FLG
为“U”。
同样,当删除记录时,我需要将 META_UPD_DT
和 META_IUD_FLG
更新为“D”。
我是 SQL 新手,因此非常感谢您的帮助。谢谢。
当源表中的记录更新时,假设名称发生更改,在 EMP_DES
表中我需要更新 DESIG
、META_UPD_DT
> 和 META_IUD_FLG
为“U”。我尝试过此操作,但它将所有标志更改为“U”。
UPDATE emp_des
SET desig = s.desig,
meta_upd_dt = to_date(current_timestamp),
meta_iud_flg = 'U',
current_flag = 'TRUE'
FROM emp_source AS s
WHERE EXISTS (SELECT * FROM emp_des WHERE id = emp_des.id);
同样,当删除记录时,我需要将 META_UPD_DT
和 META_IUD_FLG
更新为“D”。
我是 SQL 新手,所以我想让它尽可能简单。感谢您抽出宝贵时间。
最佳答案
您要求采用非触发方法(有什么方法可以在没有触发器的情况下进行更新吗?比如只有当我运行命令时才会进行更新?)。虽然我非常喜欢基于触发器的方法,但这里有一个示例存储过程:
请注意,与触发器不同,“current_timestamp”的使用不会是在每个单独事件实际发生时,而是在执行存储过程时,而这些根本不是同一件事。
CREATE OR REPLACE PROCEDURE update_emp_des()
AS
BEGIN
-- Update existing records
UPDATE emp_des
SET desig = s.desig,
meta_upd_dt = CURRENT_TIMESTAMP,
meta_iud_flg = 'U',
current_flag = TRUE
FROM emp_source AS s
WHERE emp_des.id = s.id AND emp_des.desig != s.desig;
-- Insert new records
INSERT INTO emp_des (id, name, desig, META_CRT_DT,
meta_upd_dt, meta_iud_flg, current_flag)
SELECT id, name, desig,
CURRENT_TIMESTAMP AS crt,
CURRENT_TIMESTAMP AS upd,
'I' AS iud, TRUE AS flag
FROM emp_source
WHERE NOT EXISTS (SELECT * FROM emp_des WHERE emp_source.id = emp_des.id);
-- Delete records
UPDATE emp_des
SET meta_upd_dt = CURRENT_TIMESTAMP,
meta_iud_flg = 'D',
current_flag = FALSE
WHERE NOT EXISTS (SELECT * FROM emp_source WHERE emp_source.id = emp_des.id);
END;
此存储过程更新 emp_des 表中现有记录的 desig、meta_upd_dt 和 meta_iud_flg 列,其中 desig 列在 emp_source 表中已更改。
它还会将 emp_source 表中的新记录插入到 emp_des 表中,并更新已从 emp_source 表中删除的记录的 meta_upd_dt、meta_iud_flg 和 current_flag 列。
您可以将此存储过程分成 3 个部分并分别运行它们,如果卷很大并且您希望最大程度地减少任何锁定效果,这可能会很有用(存储过程方法的另一个缺点是如何管理锁)。
关于基于源表的 SQL INSERT、UPDATE 和 DELETE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76186829/