【问题标题】:SQL developer: How to make log output from a trigger?SQL 开发人员:如何从触发器中输出日志?
【发布时间】:2018-10-15 08:39:48
【问题描述】:

我在 SQL 中做了一个触发器,需要他在表中插入一个新行后写一个输出。请看示例:

CREATE OR REPLACE TRIGGER GAS_CODES AFTER
  INSERT ON blablatable
FOR EACH ROW

BEGIN 
insert into blabla2table (...,...,...,...)
values (:new...,...,...,..);
---output:
dbms_output.put_line('New row has been added.');
END;
/

当我编译触发器时,它会显示在脚本输出中,但如果我在表中添加新行,则什么都没有。

【问题讨论】:

  • 编译触发器不会显示dbms_output.put_line()的输出,因为代码在编译期间没有执行。当你编译它时,你究竟看到了什么?为了查看任何 dbms_output,您必须在使用 dbms_output 的任何语句之前运行 set serveroutput on。您在运行您希望输出显示的插入之前是否这样做了?
  • 是的,我以前做过。
  • @Mira7 触发器通常不用于显示任何消息。触发器是在基表上发生任何 DML 操作时应该发生的事件。不知道为什么要在触发器中写 DBMS_OUT
  • 当你说 "there's nothing" 你是指blablatable(插入目标)还是blabla2table(触发目标)?
  • 好吧,我的想象是,在添加行之后。触发器会将行复制到其他表中写入控制台内容(用户信息)。

标签: oracle plsql oracle-sqldeveloper database-trigger dbms-output


【解决方案1】:

您缺少SET SERVEROUTPUT ON。 SQLDeveloper 也可以理解此命令。

让我们在 SQLDeveloper 中做一个快速测试。

CREATE USER "TEST_SCHEMA" IDENTIFIED BY "TEST";

已创建用户“TEST_SCHEMA”。

GRANT UNLIMITED TABLESPACE TO "TEST_SCHEMA";

授权成功。

CREATE TABLE "TEST_SCHEMA"."NAMES" ("ID" NUMBER, "NAME" VARCHAR2(25), PRIMARY KEY("ID")); 

已创建表“TEST_SCHEMA”。“NAMES”。

CREATE OR REPLACE TRIGGER "TEST_SCHEMA"."NAMES_TRG_1" AFTER
  INSERT ON "TEST_SCHEMA"."NAMES"
  FOR EACH ROW
  BEGIN
    DBMS_OUTPUT.PUT_LINE('New row has been added.');
  END;
/

已编译触发器 NAMES_TRG_1

SET SERVEROUTPUT ON

此命令不会在 SQL Developer 中打印任何内容。这里不用担心。

INSERT INTO "TEST_SCHEMA"."NAMES" VALUES (1, 'Mark Smith');

插入 1 行。

已添加新行。

如您所见,输出就在那里,它是在将实际行插入表中之后插入的。工作正常。

要清理测试用例,请运行:

DROP USER "TEST_SCHEMA" CASCADE;

编辑 1:

当您使用表数据编辑器时,它的行为会有所不同。表数据编辑器有自己的 Oracle 会话,它有不同的方式来捕获 DBMS 输出。

要打开 DBMS 捕获窗口,您需要单击 "VIEW" 菜单并选择 "DBMS Output" 选项。

然后点击绿色加号按钮并设置数据库,将被捕获。

现在你可以看到输出了。

注意因为这里的输出不是“实时”的,这个窗口只有在缓冲区刷新时才会显示,并且缓冲区刷新不能手动/直接调用。

【讨论】:

  • 该死....我把一切都和你一样,但我看不到这一点。我再说一遍,我已经写了 set SERVEROUTPUT ON。在我的触发器中,只有开始插入行到另一个表,dbms_output.pu_line('something') 并结束。就这样。如果我编译代码,我可以看到 Trigger 已编译,我的 dbms 输出。但是当我添加行时,我只能看到插入和提交成功。
  • 可能是问题,当我在表中插入行而不是命令时?
  • @Mira7 什么版本的数据库?如果它较旧,则可能无法使用较新的 SQL Developer 副本捕获 dbms_output
  • 这实际上是问题所在。尝试在表中手动添加这些值。它仍然有效吗?
  • 对不起,我误解了你的问题。当您在“表格编辑器”(在“数据”选项卡中)中插入行时,这是不同的。它有自己的 Oracle 会话,并且 DBMS_OUTPUT 的捕获方式不同。您可以打开 VIEW 菜单并选择“DBMS 输出”。请注意,此处的消息不会立即显示,而是仅在输出缓冲区刷新后显示,无法手动调用。
【解决方案2】:

客户端(SQLDeveloper)很可能没​​有读取输出缓冲区。 要启用此功能,您必须从菜单“查看”->“dbms 输出”中进行选择,然后单击 dbms 输出窗口中的绿色“+”以读取连接的输出缓冲区...

在 sqlplus 中你可以这样做:

SQL> drop table tst purge; 

Table dropped.

SQL> drop table tst2 purge; 

Table dropped.

SQL> create table tst ( tst_no integer); 

Table created.

SQL> create table tst2 ( tst_no integer); 

Table created.

SQL> create or replace trigger tst_trg after insert on tst 
for each row 
begin
insert into tst2 (tst_no) values (:new.tst_no); 
dbms_output.put_line('new row with tst_no='|| :new.tst_no); 
end; 
/  2    3    4    5    6    7  

Trigger created.

SQL> set serveroutput on; 
exec dbms_output.enable; 

insert into tst values (1); SQL> 
PL/SQL procedure successfully completed.

SQL> SQL> 
new row with tst_no=1

1 row created.

SQL> r
  1* insert into tst values (1)
new row with tst_no=1

1 row created.

SQL> select * from tst2; 

    TST_NO
----------
     1
     1

SQL> 

如您所见,输出在 sqlplus 中被读取和打印,并且行被插入到目标表 tst2 中

希望对你有帮助……

【讨论】:

  • @APC “当我编译触发器时,它会显示在脚本输出中” - 显示什么?还是认为这里最可能的问题是没有启用从输出缓冲区读取。
  • @APC: 是的——正如 Miroslav Duník 在这种情况下所说的那样——通过发出“set serveroutput on”来启用它来打印输出缓冲区——当 Mira7 说“当我编译触发器,它显示在脚本输出中”我猜文本是“已编译的触发器 GAS_CODES” - 即使未设置服务器输出,该文本也会显示 - 来自输出缓冲区的文本需要设置服务器输出以显示在脚本输出中
  • 明确一点 - 如果我编译触发器,我可以看到 dbms_out 输出。但这不是我想看到的。我希望每次添加新行时都能看到这个 dbms。
  • @Mira7 - 你看到表“blabla2table”中的行了吗?要查看 dbms_output 中的内容,您必须在读取输出缓冲区的同一会话中执行插入操作。
  • @mira7 - DBMS_OUTPUT 实际上只是为开发人员提供便利。如果您希望每次都在 Oracle SQL Developer 中看到它,您可以设置配置,以便默认启用 serveroutput。但这在其他实施例中对您没有帮助。
猜你喜欢
  • 2021-04-26
  • 2012-07-05
  • 1970-01-01
  • 2022-12-06
  • 2021-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多