2012-07-07 118 views
0

人,遷移觸發器Oracle到SQL Server

我需要將Oracle觸發器遷移到SQL服務器,但我做不到。

Oracle中的觸發器很簡單:

CREATE OR REPLACE TRIGGER trigger_teste  
BEFORE INSERT OR UPDATE 
ON teste 
FOR EACH ROW 
DECLARE 
BEGIN 
:new.id  := (coalesce(:NEW.id,  0)); 
:new.vlr_sal := (coalesce(:NEW.vlr_sal, 0.00)); 
END; 

我嘗試了幾種方法,但沒有成功!

感謝您的幫助!

+1

你可以發佈任何一種方式或你得到什麼異常? – 2012-07-07 05:01:16

+2

Oracle使用PL/SQL,SQL Server使用TSQL--沒有可能的直接應用程序。你發佈的內容屬於DEFAULT約束,而不是觸發器。 – 2012-07-07 05:03:17

+0

@OMGPonies:默認聲明的行爲與觸發器實現的行爲不同。 – 2012-07-07 08:34:50

回答

1

這不適合在任何風格的RDBMS中使用觸發器。 SQL標準允許我們在使用the DEFAULT constraint syntax創建表格時定義默認值。 Oracle和SQL Server都有。

很明顯,您在創建表格時沒有這樣做。好消息是我們可以使用ALTER TABLE來添加默認約束。像這樣的東西

alter table teste 
    alter column id set default 0 

這是SQL Server。在Oracle這將是:

alter table teste 
    modify id default 0 

由於無名馬指出,對於觸發一個完整的更換必須包括對受影響的列NOT NULL約束。如果現有的表不缺少空約束,我們可以使用與上面所示相同的語法來添加它們,用NOT NULL替代DEFAULT子句 - 或者甚至在同一個語句中組合兩個子句。

+1

默認值*不會與觸發器做同樣的事情。僅當該列未在插入語句中傳遞時才適用默認值。它不會阻止直接更新爲NULL或明確傳遞空值。觸發器會(默默地)用非空值替換它(這與聲明列「not null」不同) – 2012-07-07 08:34:12

1

我的T-SQL有點生疏,但像這樣的東西應該工作。請注意,SQL服務器沒有行級觸發器,只有語句級觸發器。

CREATE TRIGGER trigger_teste  
ON teste 
BEFORE INSERT OR UPDATE 
AS 
    update inserted 
     set  id = coalesce(id, 0), 
      vlr_sal = coalesce(vlr_sal, 0.0) 
GO 

(不知道如果我得到錯過了一個分號或不我永遠無法理解當SQL Server需要或deosn't需要一個)

詳情請參見本手冊:

http://msdn.microsoft.com/en-US/library/ms189799%28v=sql.90%29
http://msdn.microsoft.com/en-US/library/ms191300%28v=sql.90%29

+0

此更新語句將觸擊表中的每一行。因此,它在性能上可能相當昂貴。所以,雖然我同意這是OP正在尋找的具體答案,但我仍然認爲限制仍然是更好的實施。 – APC 2012-07-08 11:06:44

+0

@APC:不,它不會。它只會「打」受D​​ML操作影響的那些,因爲「插入的」「虛擬表」只包含修改/插入的行。 SQL Server觸發器與Oracle根本不同(主要是因爲SQL Server沒有行級觸發器) – 2012-07-08 15:45:10

+0

好吧,這是一個有趣的事實,可以添加到我的小型T-SQL知識庫中。但是它仍然不能讓我改變我的立場:任何可以在沒有觸發器的情況下完成的任何事情都應該在沒有觸發器的情況下完成。 – APC 2012-07-08 16:17:13