我编写了一个PL / SQL包,其中所有应用程序代码都在hr模式中的表上运行。我想写一个触发器来响应在employee表上执行的任何DML语句。
你能在PL / SQL包中编写一个触发器吗?。我的意思是你可以在一个包装内写下所有东西,所以从技术上讲,一个人应该能够在一个包装内写一个触发器。
我知道我也可以将此触发器创建为数据库对象。 但我希望此触发器属于包的范围。
是否可以在响应包裹代码执行的DML语句时“触发”触发器?
感谢您的意见/建议!!!
答案 0 :(得分:2)
如果您希望触发器的代码仅在DML由您的包启动时运行,我的方法是在您的包中使用全局布尔值,例如
my_pkg_running boolean := FALSE;
在你的包裹中,用以下内容包装你的DML:
my_pkg_running := TRUE;
... execute the DML here ...
my_pkg_running := FALSE;
然后,您的触发器应调用包过程,例如
my_pkg.trigger_fired;
哪个代码会像这样:
PROCEDURE trigger_fired IS
BEGIN
IF my_pkg_running THEN
... your trigger code ...
END IF;
END trigger_fired;
这样,如果触发器是从不是来自包的DML触发的,那么trigger_fired
过程将什么都不做。
答案 1 :(得分:2)
触发器是包中的一个单独的数据库对象,当发生BEFORE UPDATE ON xxxx
或AFTER INSERT ON yyyy
等触发操作时,没有直接的方法可以在包中执行一段代码。当然,您可以以调用打包例程的方式对触发器进行编码,类似于:
CREATE OR REPLACE PACKAGE TRIGGER_PACKAGE AS
PROCEDURE MY_TRIGGER_PROC;
END TRIGGER_PACKAGE;
CREATE OR REPLACE PACKAGE BODY TRIGGER_PACKAGE AS
PROCEDURE MY_TRIGGER_PROC IS
BEGIN
DBMS_OUTPUT.PUT_LINE('TRIGGER_PACKAGE.MY_TRIGGER_PROC invoked');
END MY_TRIGGER_PROC;
END trigger_package;
CREATE OR REPLACE TRIGGER MY_TABLE_AIUD
AFTER INSERT UPDATE DELETE ON MY_TABLE
FOR EACH ROW
BEGIN
TRIGGER_PACKAGE.MY_TRIGGER_PROC;
END MY_TABLE_AIUD;
但是,通过这样做,您将无法访问:NEW和:OLD值,并且无法确定触发器的调用方式/原因(例如INSERTING,UPDATING和DELETING booleans),因此我不能推荐这作为实现触发器的方法。 YMMV。
分享并享受。
答案 2 :(得分:0)
不,它可能会在包中写入触发器。虽然您可以从触发器调用包的实现部分