9

我在 Oracle 中调试触发器时遇到了困难。目前我正在使用 Oracle 的 Sql Developer 工具。

为了测试触发器,我在测试窗口中编写了插入或删除,但我看不到触发器内部发生了什么。我想逐步检查触发器,看看触发器触发时发生了什么。有没有办法使用 select 语句在触发器中显示变量值?

4

4 回答 4

14

Firstly, don't "start from here", or more specifically, don't use triggers. Triggers are going to force switching to row-level processing if the triggers are going to fire for each row. It's better to put the logic in a stored procedure which you call. You've then got a start (where you validate inputs) and an end and a logic path all the way through. Stored procedures are a lot easier to debug as you follow one path.

Second, never test for an error you don't know how to handle. If you don't catch it, it bubbles up to the client who gets an error report saying what went wrong (error message) and where (i.e. the error/call stack). If you try to catch it, you have to know what to do with it (and if you don't know the tendency is to ignore it - which is BAD).

Finally, you can't readily see each 'layer' of a select. The explain plan will generally tell you how its going about things. v$session_longops MAY indicate what it is currently doing. The current wait event MAY give clues as to what table/block/row it is currently working on.

于 2010-09-17T01:56:16.310 回答
10

如果您必须调试触发器,一个粗略的简单方法是使用DBMS_OUTPUT

例如

SQL> CREATE OR REPLACE TRIGGER mytrigger
     BEFORE UPDATE ON mytable
     FOR EACH ROW
     ...
     BEGIN
       DBMS_OUTPUT.put_line('mytrigger STARTING');
       ... do some logic ...
       DBMS_OUTPUT.put_line('old=' || :OLD.mycolumn);
       DBMS_OUTPUT.put_line('new=' || :NEW.mycolumn);
       DBMS_OUTPUT.put_line('mytrigger FINISHED');
     END;
     /

SQL> SET SERVEROUT ON
SQL> UPDATE mytable SET mycolumn = mycolumn + 1;
2 rows updated.

mytrigger STARTING
old=10
new=11
mytrigger FINISHED
mytrigger STARTING
old=20
new=21
mytrigger FINISHED
于 2010-09-17T02:53:13.710 回答
1

应用程序 我使用来自 www.quest.com/toad/toad-for-oracle.aspx 的名为 TOAD 的 Quest 程序。

如上所述,DBMS_OUTPUT 非常方便。在您的编辑器中,确保启用“输出”窗口。

PL/SQL 在代码“块”上工作,您可以使用 EXCEPTION 关键字捕获它。

(请原谅我的格式,不知道如何格式化网络)

DECLARE
    C_DATE_FORMAT VARCHAR2(20) := 'DD-Mon-YYYY';
    C_TIME_FORMAT VARCHAR2(20) := 'HH24:MI:SS';
    C_NOT_IMPLEMENTED_CODE CONSTANT NUMBER(5) := -20200;
    C_NOT_IMPLEMENTED_MESSAGE CONSTANT VARCHAR2(255) := 'Not implemented';
    not_implemented EXCEPTION; -- user defined exception
BEGIN
    --RAISE not_implemented; -- raise user defined exception
    RAISE_APPLICATION_ERROR(C_NOT_IMPLEMENTED_CODE, C_NOT_IMPLEMENTED_MESSAGE); -- user defined exception
EXCEPTION -- exception block
    WHEN not_implemented THEN -- catch not_implemented exception
        DBMS_OUTPUT.PUT_LINE('Error: Not implemented');
    WHEN OTHERS THEN -- catch all other exceptions
        DBMS_OUTPUT.PUT_LINE('Error occured.');
        DBMS_OUTPUT.PUT_LINE('Date: ' || TO_CHAR(SYSDATE, C_DATE_FORMAT));
        DBMS_OUTPUT.PUT_LINE('Time: ' || TO_CHAR(SYSDATE, C_TIME_FORMAT));
        DBMS_OUTPUT.PUT_LINE('Error code: ' || SQLCODE);
        DBMS_OUTPUT.PUT_LINE('Error message: ' || SQLERRM); --deal with error
        RAISE; -- raise to calling object
END;
于 2010-09-17T03:41:12.453 回答
0

按照以下步骤在 Oracle PL/SQL 中调试触发器

  1. 使用编辑选项打开您的触发器。通过单击行号设置断点(见下文)。 在此处输入图像描述
  2. 打开测试窗口,如下图所示。
  3. 为您的表编写插入/更新查询。(注意:您的触发器可以设置在更新/插入或两者上)
  4. 单击启动调试器按钮。

在此处输入图像描述

一旦值将在您的表中更新。调试器会带你去触发。您可以在哪里继续调试。

在此处输入图像描述

于 2020-11-23T11:02:32.737 回答