我有这个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。 我现在尝试了两天。我试图消除和简化触发器,但即使使用简单的更新命令它也无法工作。 有关错误的任何想法或任何可能给我更多错误消息或细节的工具?
由于
答案 0 :(得分:2)
首先,如果您键入&#34;显示错误&#34;在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
答案 1 :(得分:2)
使用F9执行它(在插入符处执行/编译语句)。它是编辑器工具栏上最左边的按钮,具有绿色播放按钮。你用F5作为脚本执行它。 Justin Cave指出,这需要SHOW ERRORS,但是应该保留脚本执行(超过1个语句)或者想要模拟SQL * Plus行为。单个语句执行,编译对象等最好使用F9完成。它会自动从许多其他事物中获取错误。