【问题标题】:Create Trigger with stored procedures by making dynamic in the trigger column通过在触发器列中动态创建带有存储过程的触发器
【发布时间】:2019-06-24 15:54:41
【问题描述】:

我使用存储过程创建新的触发器审计,因为需要触发器审计中的灵活列

我正在使用 Oracle 12 C ..

创建或替换过程 DBADMIN.TEST3(输出 SYS_REFCURSOR,
                                          VARCHAR2 中的表名)
是
    N号码;
开始
    N := 0;

    立即执行'

创建或替换触发器 DBADMIN.TA_EMPLOYEES3
    插入、删除或更新后
    在 DBADMIN.EMPLOYEES 上
    每一行
宣布
    SID VARCHAR2 (30);
开始
    SELECT SYS_CONTEXT ('' USERENV '', '' IP_ADDRESS '') INTO IP FROM DUAL;

    选择序列#
      进入 SID1
      FROM v$会话
     WHERE audsid = (SELECT USERENV ('' SESSIONID '') FROM DUAL);

    如果插入
    然后
        插入 DBADMIN.DBLOG_MONITORING_DETAIL2(SID,
                                                          列,
                                                          旧值,
                                                          新价值)
                 值(SID1,
                         i.COLUMN_NAME,
                        'for row in (SELECT column_name from user_tab_columns where table_name=''EMPLOYEES'' 循环
                        立即执行 '':old.row.column_name '';
                      结束循环;
/

32 26 PLS-00103:遇到符号“FOR”

我认为我的脚本逻辑不好......可以给我更好的逻辑或更好地修复我的脚本吗? .

【问题讨论】:

    标签: linux database oracle oracle12c


    【解决方案1】:

    在 Oracle 中,您应该很少使用动态 SQL 来创建数据库对象。人们有时会滥用这个功能——在我看来——你正在尝试做的事情。您可以做到这一点并不意味着您应该做到这一点,例如你可以用铅笔戳你的眼睛,但你不应该那样做。

    动态 SQL 的经验法则:

    • 忘记EXECUTE IMMEDIATE
    • 创建一个局部变量(一个大的VARCHAR2CLOB,取决于你在做什么)
    • 撰写声明(在您的情况下为CREATE TRIGGER)和
    • 将其存储到该变量中
    • 使用DBMS_OUTPUT.PUT_LINE在屏幕上显示它
    • 复制/粘贴它并作为独立语句运行
      • 如果它成功了,你已经做得很好,所以你现在可以在EXECUTE IMMEDIATE 中使用它
      • 如果失败,您将不得不更加努力地尝试、调试、修复错误并重复循环

    至于你得到的错误:这个:

    for row in (SELECT column_name from user_tab_columns where table_name=''EMPLOYEES'' loop  
      execute immediate '':old.row.column_name '';
    end loop;
    

    作为INSERT INTO 目标无效;你不能那样混合 SQL 和 PL/SQL。无论您使用动态 SQL,它都无法正常工作。此外,很明显它是错误的(缺少右括号,你究竟是在立即执行什么old_row.column_name?你将如何执行列名?

    在我看来(再一次),你不应该那样做。如果您想创建触发器,请执行此操作 - 但不是 动态

    【讨论】:

    • 感谢您的建议。我只想动态创建列,因为这是用户要求。顺便说一句,我应该在循环中做什么来检索数据列??
    猜你喜欢
    • 1970-01-01
    • 2021-10-12
    • 2013-01-22
    • 1970-01-01
    • 2021-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多