2012-07-07 136 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