SERVEROUTPUT一个接一个地执行结果

时间:2017-08-14 17:59:20

标签: oracle plsql

当我执行以下触发器代码时,它被编译。然后插入数据后,serveroutput表示插入了1行'触发结果('用户示例已输入数据')没有显示。

然后在执行另一个PL / SQL之后,先前的触发结果将出现在显示屏上。我该怎么做才能解决这个问题?

这是触发器和插入命令以及结果

/
SET SERVEROUTPUT ON;

CREATE OR REPLACE TRIGGER BTR_SUPERHEROS
BEFORE INSERT ON SUPERHEROS
FOR EACH ROW
ENABLE

DECLARE
    V_USER VARCHAR2(30);
BEGIN
    SELECT USER INTO V_USER FROM DUAL;
    DBMS_OUTPUT.ENABLE();
    DBMS_OUTPUT.PUT_LINE('USER:' ||V_USER||' HAS INSERTED A DATA');
END;
/

结果 - 触发BTR_SUPERHEROS编译

插入超级价值(' SUPERMAN');

结果 - 已插入1行。 (没有显示DBMS_OUTPUT)

1 个答案:

答案 0 :(得分:1)

在运行语句的会话中,您需要在客户端应用程序(SQL * Plus,SQL Developer等)中set serveroutput on,否则它不知道您希望它获取并显示输出语句完成时缓冲。创建触发器之前的set server output on只是一个客户端设置,并且不会为触发器永久设置它。

请确认您的测试用例是否来自单个会话,如下所示:

SQL*Plus: Release 12.1.0.1.0 Production on Tue Aug 15 08:17:48 2017

Copyright (c) 1982, 2013, Oracle.  All rights reserved.

Last Successful login time: Tue Aug 15 2017 08:14:08 +01:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options

SQL> SET SERVEROUTPUT ON;
SQL>
SQL> CREATE OR REPLACE TRIGGER BTR_SUPERHEROS
  2  BEFORE INSERT ON SUPERHEROS
  3  FOR EACH ROW
  4  ENABLE
  5
  6  DECLARE
  7      V_USER VARCHAR2(30);
  8  BEGIN
  9      SELECT USER INTO V_USER FROM DUAL;
 10      DBMS_OUTPUT.ENABLE();
 11      DBMS_OUTPUT.PUT_LINE('USER:' ||V_USER||' HAS INSERTED A DATA');
 12  END;
 13  /

Trigger created.

SQL> INSERT INTO SUPERHEROS VALUES('SUPERMAN');
USER:WILLIAM HAS INSERTED A DATA

1 row created.

另请注意,建议不要致电dbms_output.enable。来自the documentation

  

通常应避免让应用程序代码调用DISABLE Procedure或ENABLE Procedure,因为这可能会破坏SQL * Plus等外部工具的控制,以控制是否显示输出。

您还可以使用分配:=运算符而不是select into语句来分配值。因此触发器可以写成:

create or replace trigger btr_superheros
before insert on superheros
for each row
enable
declare
    v_user user_users.username%type := sys_context('userenv', 'current_schema');
begin
    dbms_output.put_line('User: ' ||v_user||' inserted value '''||:new.name||'''');
end;
/