Oracle 触发器给出未知错误
Posted
技术标签:
【中文标题】Oracle 触发器给出未知错误【英文标题】:Oracle trigger gives unknown error 【发布时间】:2016-07-21 20:07:00 【问题描述】:我有这个工作正常的 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。 我已经尝试了两天了。我试图消除和简化触发器,但即使使用简单的更新命令也无法正常工作。 有关该错误的任何想法或任何可以给我更多错误消息或详细信息的工具?
谢谢
【问题讨论】:
【参考方案1】:首先,如果您在SQL*Plus
中输入“显示错误”,您将得到实际错误。其次,您不能加入:new
伪记录。这不是一张桌子。第三,您几乎肯定不想在VM_SDetail
的行级触发器中查询VM_SDetail
。假设id
是您表的主键,我猜您只想设置: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
【讨论】:
【参考方案2】:使用 F9 执行它(在插入符号处执行/编译语句)。它是编辑器工具栏上最左边的按钮,有绿色的播放按钮。您正在使用 F5 作为脚本执行它。正如 Justin Cave 指出的那样,这需要 SHOW ERRORS ,但应为脚本执行(多于 1 条语句)或当您想要模拟 SQL*Plus 行为时保留作为脚本执行。单语句执行、编译对象等最好使用 F9 完成。它会自动获取许多其他内容中的错误。
【讨论】:
以上是关于Oracle 触发器给出未知错误的主要内容,如果未能解决你的问题,请参考以下文章