gpt4 book ai didi

oracle - 从触发器中捕获包/过程/函数名称

转载 作者:行者123 更新时间:2023-12-05 00:31:31 26 4
gpt4 key购买 nike

我有一个表(Oracle 11g),多个包/存储过程在该表上运行 DML 语句。我想使用触发器捕获在表上发出 DML 的包/过程名称,并将其记录到日志记录表中。

例如:

套餐MY_PACK.MY_PROC()发出 insert into...为表mytab .我会在 mytab 上设计一个触发器它应该能够捕获发出 insert into.. 的包/过程名称。并将此信息存储在另一个表中 my_tab_log .

我做了一些搜索,发现 $$PLSQL_UNIT$$PLSQL_LINE可以指出过程名称,但是如果在触发器内使用这些变量,则将捕获触发器名称而不是发出 DML 语句的包/过程名称。

喜欢 -

CREATE OR REPLACE TRIGGER my_trg
AFTER INSERT OR UPDATE OR DELETE
ON MY_TAB
FOR EACH ROW
BEGIN
IF INSERTING THEN
insert into my_tab_log values('INSERTED A ROW'
sysdate,
$$PLSQL_UNIT);
END IF;
-- This would capture Trigger name but I would like to capture `MY_PACK.MY_PROC()`
-- which issued the insert statement
...
END;

现在因为 $$PLSQL_UNIT 是一个条件编译指令。当您编译/重新编译 PL/SQL 代码时,它会得到解决。所以不幸的是,触发器中的 $$PLSQL_UNIT 只不过是触发器名称,并在触发器编译时解析。

我还找到了程序 owa_util.who_called_me但无法理解如何使用它来满足我的需求。甚至可以在不更改发出 DML 语句的实际包/存储过程的情况下实现我想要的吗?我无法修改这些程序,这是对它的严格限制,因此不是一种选择。

最佳答案

$$PLSQL_UNIT将只提供包名称,而不是包中的过程名称。 who_called_me也是如此.
owa_util.who_called_me是基于不可估量的 Kyte 先生编写的一个小实用程序。如果你看一眼 his source code here您将看到该例程从调用堆栈中获取其信息。因此,它提供的信息是:

  • 程序所有者
  • 程序名称(包或独立程序)
  • 程序类型
  • 行号

  • 这些公认的令人沮丧的限制归结为重载:我们可以创建具有相同名称但不同签名的打包过程。因此,在识别正在运行的代码段时,“过程名称”对系统并不是特别有用。

    不管怎样,如果你想玩玩 who_called_me ,它需要四个这样的参数:
    create or replace trigger my_trg 
    before insert or update on my_tab
    for each row
    declare
    l_owner varchar2(30);
    l_name varchar2(30);
    l_line pls_integer;
    l_type varchar2(30);
    begin
    owa_util.who_called_me(l_owner,l_name,l_line,l_type);
    IF INSERTING THEN
    insert into my_tab_log values('INSERTED A ROW'
    sysdate,
    l_owner||'.'||l_name);
    END IF;
    end;
    /

    关于oracle - 从触发器中捕获包/过程/函数名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14554891/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com