ORACLE PL/SQL 触发器使用两个不同的表
Posted
技术标签:
【中文标题】ORACLE PL/SQL 触发器使用两个不同的表【英文标题】:ORACL PL/SQL Trigger Using Two different tables 【发布时间】:2017-09-29 12:20:23 【问题描述】:除了编写迁移 SQL 和一些基本触发器之外,我对 PL/SQL 主题的经验并不多。因此,我会直接问我的问题,以便在我期望的表的触发器中至少有一个起点。
我们有以下表格:
VIB: Varchar
Locale: Varchar
Status : Varchar
Released : boolean
我需要D2C_EVENT_GENERATION_MASTER
表上的触发器,要求是,某些系统会在此表中插入“vib”列没有 vib 的 LOCALE 值 .所以我们的期望是在该系统的插入操作之前计算语言环境(从 release_table 中找到合适的语言环境),通过向RELEASE_TABLE
询问该VIB
存在的适当语言环境,并且发布标志为“真”。
CREATE OR REPLACE TRIGGER BL_D2C_EVENT_GENERATION_MASTER
BEFORE INSERT
ON D2C_EVENT_GENERATION_MASTER
FOR EACH ROW
DECLARE
l_locale varchar2(100);
BEGIN
if :NEW.locale is null then
for rec in (select locale from RELEASE_TABLE@pdpe.mch.bshg.com where vib=:NEW.vib AND released = 1)
loop
INSERT INTO d2c_event_generation_master (vib,locale) VALUES (:NEW.vib,rec.locale);
end loop;
DELETE FROM d2c_event_generation_master where vib=:NEW.vib AND locale is null;
end if;
END;
我即将创建此触发器,但只发生了一个我无法修复的异常。当我在这样的表中插入具有空区域设置值的行时:
INSERT INTO D2C_EVENT_GENERATION_AP (vib) values ('GP200046');
它从其他表中获取语言环境,但插入三行:
GP200046 fr-BE
GP200046 nl-BE
GP200046 null
我不想在这里看到“null”,我尝试了一些立即执行或其他一些人员,但找不到任何东西。
你能帮忙吗?
【问题讨论】:
你对 LOCALE 做了什么样的计算?您是否从另一个表中检索数据的数学计算? 想象一下,这只是一个类似“select vib from release_table where released = true”的查询,对于响应语言环境,我应该使用这些语言环境创建插入或更新到其他表。 因此,如果我理解正确,有人将只插入没有语言环境的主键 D2C_EVENT_GENERATION_MASTER 表,然后您需要查询 RELEASE 表以获取使用 VIB 列连接两个表的语言环境值,对吗? ? 没错!发布表将为我提供必要的语言环境,这些表可以使用 VIB 列轻松连接。 好的,那么触发器是要走的路,对于第二个触发器,您希望首先比具有 VIB 和区域设置的行不存在于状态不同的表中 NEW,如果是这种情况,那么您只需将状态更新为 NEW? 【参考方案1】:这是插入前的触发器,用于从发布表中获取值:
CREATE OR REPLACE TRIGGER BI_D2C_EVENT_GENERATION_MASTER
BEFORE INSERT
ON D2C_EVENT_GENERATION_MASTER
FOR EACH ROW
DECLARE
l_locale varchar2(100);
BEGIN
if :NEW.locale is null then
select locale INTO l_locale from release where vib=:NEW.vib;
:NEW.locale := l_locale;
end if;
END;
/
编辑:
对于第二种解决方案,我建议创建一个程序:
CREATE OR REPLACE PROCEDURE MI_D2C_EVENT_GENERATION_MASTER (p_vib number, p_locale varchar2)
IS
l_vib number := p_vib;
l_locale varchar2(100) := p_locale;
BEGIN
MERGE INTO D2C_EVENT_GENERATION_MASTER event
USING (SELECT vib, locale from D2C_EVENT_GENERATION_MASTER) old_event
ON (event.vib = l_vib
and event.locale = l_locale)
WHEN MATCHED THEN
UPDATE SET event.STATUS = 'NEW'
WHERE event.STATUS != 'NEW'
WHEN NOT MATCHED THEN
INSERT (vib,locale,status) VALUES (l_vib, l_locale, 'STATUS')';
END;
/
【讨论】:
为什么选择动态 SQL? @WilliamRobertson 你说得对,没必要,我更新了答案。 触发器仍然是动态的。 大家好,如果可能的话,你能检查我的编辑吗?关于从表中删除空值?答案也没有涵盖多行条件,我编辑了循环以在我的问题上使用它。以上是关于ORACLE PL/SQL 触发器使用两个不同的表的主要内容,如果未能解决你的问题,请参考以下文章
Oracle 12 PL/SQL 在触发器中检索存储过程名称
如何使用间隔 1 分钟在两个日期之间将时间序列数据生成到 Oracle PL/SQL 中的表中?