如何从过程传递参数以触发 Oracle 中的 PL SQL
how to pass an argument from a procedure to trigger PL SQL in oracle
知道我要发送的参数 (id_empl) 没有存储在数据库中,所以我无法使用 :NEW.id_empl 或 :OLD.id_empl[=12 检索它=]
--my procedure
create or replace procedure delete_pdb(
id_pdb IN pdb.id%TYPE,
id_empl IN empl.id%TYPE)
IS
BEGIN
delete from pdb where id=id_pdb;
END delete_pdb;
/
--my trigger
create or replace trigger archive_pdb
AFTER UPDATE OR DELETE on pdb
FOR EACH ROW
begin
--i want to pick it up here (id_empl)
end;
你不能。
您可以使用 :OLD.id
获取 id_pdb
值,因为这是已删除的 table 中的一个值,但您无法获取 id_empl
值,因为它与DELETE
动作。
db<>fiddle here
id_empl 与 table pdb 无关。只有您调用的函数知道它。因此,在处理 table 上的操作的触发器中使用它似乎是错误的地方。
据我所知,您似乎想在日志记录中存储负责该操作的员工 table。通常人们会简单地存储当前用户,但是在具有连接池的环境中,例如所有用户共享相同的登录帐户,这没有帮助。
处理此问题的一种方法是改为存储 OSUSER:
SELECT SYS_CONTEXT('USERENV', 'OS_USER') FROM DUAL;
如果这还不够,您必须改为存储 id_empl,则您必须记住会话上下文中的 id_empl 并从那里使用它。一种简单的方法是使用带有 public 变量的 PL/SQL 包。
包头
CREATE OR REPLACE PACKAGE pk_pdb_actions IS
pkv_id_empl empl.id%TYPE;
BEGIN
PROCEDURE delete_pdb(p_id_pdb IN pdb.id%TYPE, p_id_empl IN empl.id%TYPE);
...
END pk_pdb_actions;
包体
CREATE OR REPLACE PACKAGE BODY pk_pdb_actions IS
BEGIN
PROCEDURE delete_pdb(p_id_pdb IN pdb.id%TYPE, p_id_empl IN empl.id%TYPE) IS
BEGIN
pkv_id_empl := p_id_empl;
DELETE FROM pdb WHERE id = p_id_pdb;
END delete_pdb;
...
END pk_pdb_actions;
触发器
CREATE OR REPLACE trigger trg_archive_pdb
AFTER UPDATE OR DELETE on pdb
FOR EACH ROW
BEGIN
INSERT INTO archive_pdb (id_empl, id_pdb)
VALUES (pk_pdb_actions.pkv_id_empl, :old.id);
END trg_archive_pdb;
知道我要发送的参数 (id_empl) 没有存储在数据库中,所以我无法使用 :NEW.id_empl 或 :OLD.id_empl[=12 检索它=]
--my procedure
create or replace procedure delete_pdb(
id_pdb IN pdb.id%TYPE,
id_empl IN empl.id%TYPE)
IS
BEGIN
delete from pdb where id=id_pdb;
END delete_pdb;
/
--my trigger
create or replace trigger archive_pdb
AFTER UPDATE OR DELETE on pdb
FOR EACH ROW
begin
--i want to pick it up here (id_empl)
end;
你不能。
您可以使用 :OLD.id
获取 id_pdb
值,因为这是已删除的 table 中的一个值,但您无法获取 id_empl
值,因为它与DELETE
动作。
db<>fiddle here
id_empl 与 table pdb 无关。只有您调用的函数知道它。因此,在处理 table 上的操作的触发器中使用它似乎是错误的地方。
据我所知,您似乎想在日志记录中存储负责该操作的员工 table。通常人们会简单地存储当前用户,但是在具有连接池的环境中,例如所有用户共享相同的登录帐户,这没有帮助。
处理此问题的一种方法是改为存储 OSUSER:
SELECT SYS_CONTEXT('USERENV', 'OS_USER') FROM DUAL;
如果这还不够,您必须改为存储 id_empl,则您必须记住会话上下文中的 id_empl 并从那里使用它。一种简单的方法是使用带有 public 变量的 PL/SQL 包。
包头
CREATE OR REPLACE PACKAGE pk_pdb_actions IS
pkv_id_empl empl.id%TYPE;
BEGIN
PROCEDURE delete_pdb(p_id_pdb IN pdb.id%TYPE, p_id_empl IN empl.id%TYPE);
...
END pk_pdb_actions;
包体
CREATE OR REPLACE PACKAGE BODY pk_pdb_actions IS
BEGIN
PROCEDURE delete_pdb(p_id_pdb IN pdb.id%TYPE, p_id_empl IN empl.id%TYPE) IS
BEGIN
pkv_id_empl := p_id_empl;
DELETE FROM pdb WHERE id = p_id_pdb;
END delete_pdb;
...
END pk_pdb_actions;
触发器
CREATE OR REPLACE trigger trg_archive_pdb
AFTER UPDATE OR DELETE on pdb
FOR EACH ROW
BEGIN
INSERT INTO archive_pdb (id_empl, id_pdb)
VALUES (pk_pdb_actions.pkv_id_empl, :old.id);
END trg_archive_pdb;