在 Oracle 11g 中创建触发器的问题

Posted

技术标签:

【中文标题】在 Oracle 11g 中创建触发器的问题【英文标题】:Problems creating a trigger in Oracle 11g 【发布时间】:2013-06-02 13:23:51 【问题描述】:

尝试使用 SQL Developer 在我的 Oracle 11g 数据库中创建触发器时遇到一个奇怪的错误。这是我所做的:

我的桌子:

CREATE TABLE COUNTRY_CODE(
   ID NUMBER(19,0)      PRIMARY KEY NOT NULL, 
   Code             VARCHAR2(2) NOT NULL,
   Description  VARCHAR2(50),
   created                  TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 
   created_by                   VARCHAR2(40) DEFAULT USER, 
   last_updated                 TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 
   last_updated_by          VARCHAR2(40) DEFAULT USER,
   archived CHAR(1) DEFAULT '0' NOT NULL );

顺序:

CREATE SEQUENCE COUNTRY_CODE_ID_SEQ START WITH 1 INCREMENT BY 1;

触发器:

CREATE OR REPLACE TRIGGER COUNTRY_CODE_TRIGGER
BEFORE INSERT ON COUNTRY_CODE
FOR EACH ROW
DECLARE
    max_id number;
    cur_seq number;
BEGIN
    IF :new.id IS NULL THEN
    SELECT COUNTRY_CODE_ID_SEQ.nextval
    INTO :new.id
    FROM dual;
ELSE
    SELECT GREATEST(NVL(MAX(id),0), :new.id)
    INTO max_id
    FROM COUNTRY_CODE;

    SELECT COUNTRY_CODE_ID_SEQ.nextval
    INTO cur_seq
    FROM dual;

    WHILE cur_seq < max_id
    LOOP
        SELECT COUNTRY_CODE_ID_SEQ.nextval
        INTO cur_seq
        FROM dual;
    END LOOP;
END IF;
END;

创建表和序列效果很好,但是当我尝试创建触发器时,我收到了这个错误:

Error report:
ORA-00603: ORACLE server session terminated by fatal error
ORA-00600: internal error code, arguments: [kqlidchg0], [], [], [], [], [], [], [], [], [], [], []
ORA-00604: error occurred at recursive SQL level 1
ORA-00001: unique constraint (SYS.I_PLSCOPE_SIG_IDENTIFIER$) violated
00603. 00000 -  "ORACLE server session terminated by fatal error"
*Cause:    An ORACLE server session is in an unrecoverable state.
*Action:   Login to ORACLE again so a new server session will be created

有人知道这个错误吗?

谢谢

【问题讨论】:

一旦您修复了 PLScope 问题,您将获得一个变异触发器异常。不允许COUNTRY_CODE 上的行级触发器查询COUNTRY_CODE 表。虽然可以使用额外的语句级触发器来解决此问题,但您似乎不太可能真的需要在每次插入一行时检查序列是否需要重置。在极少数情况下,您可能只想将序列设置为更大的值,因为某些情况会导致创建此错误条件。 【参考方案1】:

我终于找到了我的问题的答案:

添加这个:

ALTER SESSION SET PLSCOPE_SETTINGS = 'IDENTIFIERS:NONE';

或者在 Oracle SQL Developer 中:

    转到工具 |偏好 选择数据库 | PL/SQL 编译器 将 PLScope 标识符从 All 更改为 None 点击确定

这解决了问题...

【讨论】:

这解决了我的问题。但是为什么会发生呢?究竟是什么问题?【参考方案2】:

这个here.可能有解决方案

【讨论】:

谢谢托尼,非常感谢! @TonyAndrews 尽量避免只有超链接的答案。如果链接断开,则此答案将毫无用处。您可能希望修改您的答案以发布您所学内容的摘要,然后参考链接。 @vapcguy 点了,但是因为这个答案是 3 岁而不是被接受的答案,我可能不会! @TonyAndrews 也许,如果您的答案不是链接,那么它会在您第一次回答时被接受... 哦,好吧...这是 5 年前的 :-)【参考方案3】:

我没有其他解决方案(也没有仅仅发表评论的声誉),但这里有一些信息可能有助于让某人走上正确的轨道来解决这个问题,同时仍然使用 PL/Scope。

我刚刚遇到了类似的问题,研究 PL/Scope 功能帮助我了解了问题可能出在哪里。对于我的问题,我尝试创建一个触发器,但出现了同样的错误。我更改了触发器的主体无济于事,但更改名称效果很好。

似乎 PL/Scope 在删除它之前保留了有关第一个实例化触发器的信息。对触发器的查询显示我的触发器肯定已被删除,但对(PL/Scope)标识符(“all_identifiers”)的查询显示它仍然存在。

关于 PL/Scope 的一些信息在这里: http://www.oracle.com/technetwork/testcontent/o67asktom-101004.html

这里的第 8 章(11g 文档)有更多信息: http://docs.oracle.com/cd/B28359_01/appdev.111/b28424.pdf

【讨论】:

以上是关于在 Oracle 11g 中创建触发器的问题的主要内容,如果未能解决你的问题,请参考以下文章

创建一个监听多个表的全局触发器

使用 oracle 触发器审计 50 列

使用 oracle 触发器审计 50 列

Oracle 自动增量触发器问题

在 Oracle Express 中创建触发器

如何使用触发器在 oracle 中创建镜像表?