PL/SQL 触发器不工作

Posted

技术标签:

【中文标题】PL/SQL 触发器不工作【英文标题】:PL/SQL trigger not working 【发布时间】:2017-11-26 15:28:33 【问题描述】:

我已经创建了一个这样的表:

CREATE TABLE table_name (
name     VARCHAR2(20)
);

之后,我创建了一个触发器,在每次插入之前,必须写入用户名:

SET SERVEROUTPUT ON;

CREATE OR REPLACE TRIGGER bi_trigger
BEFORE INSERT ON table_name
FOR EACH ROW
ENABLE
DECLARE
v_user      VARCHAR2(20);
BEGIN
SELECT user INTO v_user FROM dual;
DBMS_OUTPUT.PUT_LINE('You inserted a row, ' || v_user);
END;

但是,在我的表中插入一些内容后,没有出现带有用户名的请求行。我错过了什么?

INSERT INTO table_name VALUES('qwerty');

【问题讨论】:

不确定您的期望。您是说即使在 COMMIT 之后新行也不会出现?由于触发器存在于会话之外,因此您不会看到 dbms_output。还有 v_user := USER;将取代从双重选择。请详细说明您的期望。 行已插入。问题是我没有看到 dbms_output。我已经编辑了我的问题。 @FogarasiNorbert 似乎没有问题,除非您没有在触发器创建语句后添加斜杠 (/),正如@Dave Costa 所说。只要您继续进行此会话,就不会出现任何问题来查看消息。 【参考方案1】:

我发现了两个潜在的问题。

一个是不清楚您是否真的在创建触发器。在您显示的示例代码中,您需要在触发器文本后面加上一个正斜杠 (/) 才能实际执行 CREATE 语句。如果创建成功,您应该会看到“已创建触发器”。

另一个是您在创建触发器之前启用了 SERVEROUTPUT,这无关紧要。您需要在执行 INSERT 语句的会话中启用它。 (如果您在与 CREATE 相同的会话中执行 INSERT,这不是问题。)

(另一个答案意味着您没有看到输出,因为触发器是在您的会话之外执行的。这是不正确的。)

【讨论】:

在创建触发器之前启用 SERVEROUTPUT 没有问题。 我并不是说这是个问题。我是说如果 INSERT 在另一个会话中执行,则需要在该会话中启用 SERVEROUTPUT 才能看到输出。编辑澄清,我希望。 @Dave Costa 我把正斜杠放在哪里了?在Enable 关键字之后? @FogarasiNorbert -- 在END;之后的那一行 另见***.com/questions/8406835/…【参考方案2】:

您不会看到 dbms_output,因为触发器存在于您的本地会话之外,未连接。如果您只想确认触发器是否正确触发,请尝试向表中添加列,例如 created_by VARCHAR2(0032)。

将您的触发器主体替换为

    :NEW.created_by := USER;

这会告诉你触发器是否工作。

【讨论】:

啊,您还需要调整插入语句以引用列“名称”。 原来您可以检索 dbms_output 但您需要使用 PL/SQL 块来执行此操作。参考:docs.oracle.com/cd/B10501_01/appdev.920/a96612/d_output.htm

以上是关于PL/SQL 触发器不工作的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL 绑定变量的问题

PL/SQL 触发器和多次更新

PL/SQL 触发器插入下一个值

在 PL/SQL 中的触发器内调用函数

PL/SQL ORACLE:删除时触发更新

为啥不允许在 PL/SQL 触发器中使用 ROLLBACK 语句,但 RAISE_APPLICATION_ERROR 是?