如何从过程传递参数以触发 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;