我有一个源表,其中包含字段IDNAMEDESIG

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(如果删除记录,则必须将其设为FALSE)

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表中,我需要将DESIGMETA_UPD_DTMETA_IUD_FLG更新为‘U’.

同样,当删除一条记录时,我需要将META_UPD_DTMETA_IUD_FLG更新为‘D’.

我是SQL的新手,所以如果有任何帮助,我将非常感激.谢谢.

当源表中的记录更新时,假设名称更改,在EMP_DES表中,我需要将DESIGMETA_UPD_DTMETA_IUD_FLG更新为‘U’. I tried this but it changes all flags to '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_DTMETA_IUD_FLG更新为‘D’.

我是SQL的新手,所以我想让它尽可能简单.感谢您抽出时间来.

推荐答案

你要求的是非触发方法(Is there any way to do updates without triggers? Like update will take place only when i run the command?).虽然我非常喜欢基于触发器的方法,但下面是一个示例存储过程:

请注意,与触发器不同,"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列,其中EMP_SOURCE表中的DESIG列已更改.

它还将emp_Source表中的新记录插入到emp_des表中,并为已从emp_Source表中删除的记录更新META_UPD_DT、META_IUD_FLG和CURRENT_FLAG列.

您可以将这个存储过程分解为3个部分,并分别运行它们,如果卷很大,并且您想要最小化任何锁定影响(存储过程方法的另一个缺点是如何管理锁),这可能会很有用.

Sql相关问答推荐

Postgres trunc_date删除一个月

删除MariaDB数据库中的JSON数据

在甲骨文中查找前一个星期一的S日期

转换表中的数据

在SQL中使用类别值将行转置为列

重新组合已排序的日期范围

SQL:如何查找聚合满足条件的连续日期

使用多个嵌套数组查询JSON数据

Oracle分层查询-两条路径在末尾合并为一条

了解多个分组集

PATINDEX中与[A-Z]匹配(U除外)的正则表达式

将一名成员金额分配给群组内的其他成员

如何为给定的股票数据集计算利润/亏损,确保先卖出先买入的股票

标量子查询中的窗口函数不起作用

Oracle PL/SQL长期运行问题

Postgres数据库维护:基于GROUP BY删除旧记录

查询以查找今天和昨天的数据之间的差异以及伪列

编写查询以根据级别 (p2) 返回父位置

使用 SAVE TRANSACTION 时 BEGIN 和 COMMIT 语句的数量不匹配

从 Pyspark 转换为具有多个分组条件的语句时的情况