Sql 触发器无效,重新验证失败

Sql 触发器无效,重新验证失败,sql,oracle,plsql,Sql,Oracle,Plsql,下面是我用来创建表、序列和触发器的代码 DROP TABLE CDR.ExtDL_JobStatus; -- -- TABLE: CDR.ExtDL_JobStatus -- CREATE TABLE CDR.ExtDL_JobStatus( Id NUMBER(38, 0) NOT NULL, ShortName NUMBER(38, 0) NOT NULL, Description NUMBER(38, 0)

下面是我用来创建表、序列和触发器的代码

DROP TABLE CDR.ExtDL_JobStatus;

-- 
-- TABLE: CDR.ExtDL_JobStatus 
--

CREATE TABLE CDR.ExtDL_JobStatus(
    Id             NUMBER(38, 0)    NOT NULL,
    ShortName      NUMBER(38, 0)    NOT NULL,
    Description    NUMBER(38, 0)    NOT NULL,
    CONSTRAINT PK_ExtDL_JobStatus PRIMARY KEY (Id)
)
;



Declare NumOfSequences NUMBER :=0;
Begin
  Select COUNT(*)
  INTO NumOfSequences
  FROM All_Sequences
  WHERE 1=1
    And upper (Sequence_Owner) = upper ('CDR')
    And upper (Sequence_Name) = upper ('ExtDL_JobStatus_Seq');
  If NumOfSequences > 0 Then
    Execute IMMEDIATE 'DROP SEQUENCE CDR.ExtDL_JobStatus_Seq';
  End If;
End;
/
CREATE SEQUENCE CDR.ExtDL_JobStatus_Seq
    INCREMENT BY 1
    START WITH 1
    NOMAXVALUE 
    NOMINVALUE 
;
/

Declare NumOfTriggers NUMBER :=0;
Begin
  SELECT COUNT(*)
  INTO NumOfTriggers
  FROM All_Triggers
  WHERE 1=1
    And upper (Owner) = upper ('CDR')
    And upper (Trigger_Name) = upper ('ExtDL_JobStatus_SeqTrg');
  If NumOfTriggers > 0 Then
    Execute IMMEDIATE 'DROP SEQUENCE CDR.ExtDL_JobStatus_SeqTrg';
  End If;
End;
/
CREATE TRIGGER CDR.ExtDL_JobStatus_SeqTrg
BEFORE INSERT
ON CDR.ExtDL_JobStatus
    FOR EACH ROW
    WHEN (new.Id IS NULL)
    BEGIN
        SELECT ExtDL_JobStatus_SeqTrg.nextval into :new.Id from dual;
    END;


/
INSERT INTO ExtDL_JobStatus (Id, ShortName, Description) Values (0, 'Success', 'Fail')
/
SELECT * FROM ExtDL_JobStatus
当我执行代码时,我得到以下输出

DROP TABLE CDR.ExtDL_JobStatus succeeded.
CREATE TABLE succeeded.
anonymous block completed
CREATE SEQUENCE succeeded.
anonymous block completed
Warning: execution completed with warning
TRIGGER CDR.ExtDL_JobStatus_SeqTrg Compiled.

Error starting at line 62 in command:
INSERT INTO ExtDL_JobStatus (Id, ShortName, Description) Values (0, 'Success', 'Fail')
Error at Command Line:62 Column:12
Error report:
SQL Error: ORA-04098: trigger 'CDR.EXTDL_JOBSTATUS_SEQTRG' is invalid and failed re-validation
04098. 00000 -  "trigger '%s.%s' is invalid and failed re-validation"
*Cause:    A trigger was attempted to be retrieved for execution and was
           found to be invalid.  This also means that compilation/authorization
           failed for the trigger.
*Action:   Options are to resolve the compilation/authorization errors,
           disable the trigger, or drop the trigger.
ID                     SHORTNAME              DESCRIPTION            
---------------------- ---------------------- ---------------------- 

0 rows selected

什么使我的触发器无效?

这是一个简单的输入错误:您的序列名为
ExtDL\u JobStatus\u Seq
,但在触发器中您引用
ExtDL\u JobStatus\u SeqTrg.nextval

为了便于将来参考,最好在编译PL/SQL(触发器、过程等)的每次调用之后包含一个调用,以显示脚本中的错误。像这样:

CREATE TRIGGER CDR.ExtDL_JobStatus_SeqTrg 
BEFORE INSERT 
ON CDR.ExtDL_JobStatus 
    FOR EACH ROW 
    WHEN (new.Id IS NULL) 
    BEGIN 
        SELECT ExtDL_JobStatus_SeqTrg.nextval into :new.Id from dual; 
    END; 
/ 

show errors
顺便说一句,匿名块中有相同的打字错误,试图删除序列

警告:执行已完成 警告触发器 CDR.ExtDL_JobStatus_SeqTrg已编译

这就是触发器编译失败的地方

sql> CREATE TRIGGER ExtDL_JobStatus_SeqTrg
  2  BEFORE INSERT
  3  ON ExtDL_JobStatus
  4      FOR EACH ROW
  5      WHEN (new.Id IS NULL)
  6      BEGIN
  7          SELECT ExtDL_JobStatus_SeqTrg.nextval into :new.Id from dual;
  8      END;
  9  /

Warning: Trigger created with compilation errors.

sql> show errors;
Errors for TRIGGER EXTDL_JOBSTATUS_SEQTRG:

LINE/COL ERROR
-------- -----------------------------------------------------------------
2/9      PL/SQL: SQL Statement ignored
2/16     PL/SQL: ORA-02289: sequence does not exist
问题是因为您在代码中使用了ExtDL\u JobStatus\u SeqTrg,并且您创建的序列是ExtDL\u JobStatus\u Seq

另外,如果您试图运行这样的脚本来创建(编译)对象,我建议您在每个触发器/过程/函数creatin语句之后添加以下子句

SHOW ERRORS;

如果您的语句成功,则不会产生错误。如果有任何错误,您将获得错误的详细描述,而不必再次执行脚本。

除了前面提到的所有内容外,还有两个额外的打字错误:

  • 试图删除触发器的匿名PL/SQL块实际上表示
    drop SEQUENCE
  • insert语句尝试在ShortName和Description列中插入字符串,这两个列都定义为NUMBER(38,0)

  • 我曾经遇到过类似的问题。我的问题是由于有多个触发器具有相同的名称,但仅在外壳上有所不同。我会检查它是否与您遇到的问题不同。@Falle1234我检查了
    select*from all_触发器
    ;没有重复项。请告诉我们实际错误是什么:
    show error CDR.EXTDL\u JOBSTATUS\u SEQTRG
    我注意到了数据类型的问题。不知何故,一切都变成了一个领域——我把它改回了每个单独的领域