Oracle 触发器给出未知错误

Oracle trigger gives unknown error

我有这个 SQL 触发器,工作正常:

    USE [DMS_TEST]
GO

IF EXISTS (SELECT object_name(id)  FROM sysobjects
   WHERE xtype ='TR' AND object_name(id) = N'TR_SALESSTATUS_CHANGE')   
   DROP TRIGGER [TR_SALESSTATUS_CHANGE]
GO

CREATE TRIGGER [TR_SALESSTATUS_CHANGE] ON [VM_SDetail] 
FOR UPDATE 
AS 
BEGIN
        Set NoCount On
        UPDATE          [VM_SDetail] 
        SET             SALESSTATUS = 1 
        From            [VM_SDetail]
                        [VM_SDetail] 
        INNER JOIN      INSERTED 
        ON              [VM_SDetail].ID = INSERTED.ID 
        Where           (Not Inserted.ValueVal Is NULL AND  (Inserted.ValueVal <> '')) 
        AND             Inserted.SALESSTATUS = 0;
End
GO

我将此触发器转换为 Oracle:

CREATE OR REPLACE TRIGGER TR_SALESSTATUS_CHANGE AFTER UPDATE
ON DMS_TEST.VM_SDetail 
FOR EACH ROW 
BEGIN
        UPDATE          DMS_TEST.VM_SDetail 
        SET             SaleStatus = 1 
        From            DMS_TEST.VM_SDetail
        INNER JOIN      :NEW 
        ON              DMS_TEST.VM_SDetail.ID = :NEW.ID 
        Where           (Not :NEW.ValueVal Is NULL AND  (:NEW.ValueVal <> '')) 
       AND             :NEW.SalesStatus = 0;
End;

我收到此警告并且触发器未按预期工作:

Warning: TRIGGER created with compilation errors.

我正在使用 TOAD。 我已经尝试了两天了。我试图消除和简化触发器,但即使使用简单的更新命令也无法正常工作。 关于错误的任何想法或任何可以给我更多错误消息或详细信息的工具?

谢谢

首先,如果您在 SQL*Plus 中键入 "show errors",您将得到实际的错误。其次,您不能加入 :new 伪记录。这不是 table。第三,您几乎肯定不想在 VM_SDetail 上的行级触发器中查询 VM_SDetail。假设 id 是 table 的主键,我猜你只想设置 :new.SaleStatus

CREATE OR REPLACE TRIGGER TR_SALESSTATUS_CHANGE AFTER UPDATE
  ON DMS_TEST.VM_SDetail 
  FOR EACH ROW 
BEGIN
  IF(    (Not :NEW.ValueVal Is NULL AND  (:NEW.ValueVal <> '')) 
     AND :NEW.SalesStatus = 0 )
  THEN
    :new.SalesStatus := 1;
  END IF;
END;

您还可以将 IF 语句放在触发器的 WHEN 子句中,这样触发器就不会真正触发,除非满足条件。那么触发主体就是 :new.SalesStatus := 1; 行。

我还应该指出,在 Oracle 中,空字符串等同于 NULL,因此没有必要检查 ValueVal 既是 NOT NULL 又不等于空字符串。直接说

更有意义
IF( :new.ValueVal IS NOT NULL and
    :new.SalesStatus = 0 )
THEN

使用 F9 执行它(Execute/compile 插入符号处的语句)。它是编辑器工具栏上最左边的按钮,带有绿色播放按钮。您正在使用 F5 作为脚本执行它。正如 Justin Cave 指出的那样,这需要 SHOW ERRORS,但是作为脚本执行应该保留用于脚本执行(超过 1 个语句)或当您想要模拟 SQL*Plus 行为时。单语句执行、编译对象等最好使用 F9 来完成。它会自动获取许多其他内容中的错误。