日期:2014-05-17  浏览次数:20623 次

吐槽SQL Server触发器
本人用T-SQL,也用PL/SQL,发现T-SQL的触发器不好用,或者说我还不太会用,

比如说一个简单表定义如下:
create table emp
(
id int,
name varchar(20),
age int,
level int
);


先说Oracle的触发器很明确,很好用。

1、前触发还是后触发
    操作之前触发用关键字Before,操作之后触发用After;
    如更新之前,用Before Update

2、针对哪个表 
    用关键字on,
    如对emp表操作时触发,用on emp

3、对哪些列操作时触发
    用关键字of
    如对name和age列操作时触发,用of name,age

4、对表的还是对行的,
    对行的就是foreach row

5、对被操作的行,要拦截字段的新、旧值
    字段新值就是:new.name,
    字段旧值就是:old.name

    对行的其它字段赋值直接,就可以new.level=5;

6、触发器的语句体
    在begin与end之间的语句就是语句体

完整的一个Oracle触发器例子如下(作用是更新x、y字段时,把shape字段一并更新):

CREATE OR REPLACE TRIGGER tr_dz_xy_point
BEFORE UPDATE OF X,Y ON DZ
FOR EACH ROW   
BEGIN
:new.Shape:=SDO_GEOMETRY (
2001, NULL,
SDO_POINT_TYPE (:new.X,:new.Y, NULL),
NULL,NULL
);
END;



对sql server(2000版)触发器的吐槽:

1、inserted、updated、deleted 代表什么?是表,是行?

    是行为什么还要这样:

    select @emp_lvl=i.level,@job_id = i.id from inserted i

    既然inserted是出现在from后面,貌似是个表,

2、怎么区分触发器是对表的还是对行?

    那如果inserted是个表,

    想引用当前被插入的这个行怎么引用?

    如果inserted.level是新值,deleted.level是旧值,(这是显而易见的)

    那updated.level是新值还是旧值,如果是新值,要读取旧值怎么办?

3、前触发与后触发的混乱

    有instead of、after、for 三类触发器,after从字面上易知是后触发,可是:

    这个for是前触发还是后触发?
    instead of又是前触发还是后触发?

4、触发器的语句体在哪?

    就是As和GO之间吗,T-SQL是没有begin/end吗,用这么拙劣的语法结构。如果没写go呢?

5、要对被操作行的其它字段赋值怎么写?

------解决方案--------------------
create table emp
(
id int,
name varchar(20),