none
关于触发器 请教一下 如何是好 RRS feed

  • 问题

  • 我使用的是SQL 2005 目前建立了两个表 belong 和 total_mileage 我的目的是希望当total_mileage中的属性total_mileage1改变了以后,启动触发器,使belong表属性中的grade相应的值发生变化 其中 我以card_number作为连接两个表


    触发器
    create trigger total_belong
    on  total_mileage
    after update
    as set nocount on
    declare @total_mileage1 float,@card_number nchar(10),@grade nchar(10) 
    select @total_mileage1=total_mileage1,@card_number=card_number from updated
    begin
    if @total_mileage1>=40000 update belong set grade='银' where card_number=@card_number
    if @total_mileage1>=80000 update belong set grade='金' where card_number=@card_number
    if @total_mileage1>=160000 update belong set grade='白金' where card_number=@card_number
    end

    目前我的问题在于 我对total_mileage表做了相应的更改 发现其中触发器只针对total_mileage中的一个元组(列表显示的最后一组)起作用,其他的元组没有任何变化,请问我应该如何是好??
    2009年12月3日 10:22

答案

全部回复

  • updated是系统表还是你建的表,有inserted,deleted没听说过updated

    一个元组(列表显示的最后一组)起作用 是指 if @total_mileage1>=160000 update belong set grade='白金' where card_number=@card_number 吗?
    我是天生我怕谁?
    2009年12月3日 12:12
  • 是这样的 我建立了的total_mileage
    card_number     total_mileage1
     1                           70000
     2                           90000
     3                          130000
     4                           40000
     5                           70000
     6                           80000
     7                          120000
     8                          200000

    belong
    grade                card_number
     银                           1
     银                           2
     银                           3
     银                           4
     银                           5
     银                           6
     银                           7
    白金                         8

    我的意思就是说 当我修改total_mileage中的total_mileage1中的数据的时候
    只有card_number=8的那个选项才能对应我的触发器做出修改而其他的所有的card_number不是8的选项,无论我如何修改都没有办法有反应
    2009年12月3日 12:27
  • 并没有updated,update触发器的数据分成两个表inserted新数据,deleted旧数据(先清除后添加)

    if update(total_mileage)
    begin
    --do anything
    end

    或者

    select * from inserted join deleted on inserted.主键=deleted.主键 where inserted.total_mileage!=deleted.total_mileage
    。。。
    注意inserteddeleted可能有多条数据

    2009年12月3日 13:42
  • CREATE TRIGGER [total_belong]
       ON  [dbo].[total_mileage]
       AFTER UPDATE
    AS set nocount on

    if update(total_mileage1)
    BEGIN
    declare @total_mileage1 float,@card_number nchar(10),@grade nchar(10)
    SELECT  @total_mileage1=total_mileage1,@card_number=card_number FROM total_mileage
        if @total_mileage1>=40000
           update belong
           set grade='银' where card_number=@card_number
        if @total_mileage1>=80000
           update belong
           set grade='金' where card_number=@card_number
        if @total_mileage1>=160000
           update belong
           set grade='白金' where card_number=@card_number
    END

    是这样吗  但是问题仍然存在

    2009年12月3日 14:06
  • create trigger total_belong on total_mileage for update as
    begin
    	set nocount on
    	if update(total_mileage1)
    	begin
    		update belong set grade=
    		case
    			when t.total_mileage1>=160000 then '白金'
    			when t.total_mileage1>=80000 then '金'
    			when t.total_mileage1>=40000 then '银'
    		end
    		from inserted t where belong.card_number=t.card_number
    	end
    end
    条件要分顺序
    2009年12月4日 3:54
  • 貌似还是没有对  看来是软件问题?????

    2009年12月4日 4:22
  • 楼主的意思是对total_mileage表的多条记录的total_mileage1字段发生了变化,但触发器只修改belong 表的最后一条记录?

    如果是这样的话,试着通过游标来访问inserted表,因为该表是一个多记录行集合,SQL的触发器并不是行级的触发器,而是语句级别的触发器,只针对一个语句触发一次,因此,所有在一个语句中被

    update改过的记录都在inserted表中,楼主的代码只为触发器提供一个card_number
    select @total_mileage1=total_mileage1,@card_number=card_number from inserted,触发器自然不能
    修改所有的记录了。是你的代码写法有问题。

     

    create trigger total_belong
    on  total_mileage
    after update
    as
     set nocount on
     declare @total_mileage1 float,@card_number nchar(10)

     select * into #temp from inserted

     DECLARE mycur CURSOR FOR
     SELECT total_mileage1,card_number
     FROM #temp


     open mycur

     FETCH NEXT FROM mycur
     INTO @total_mileage1,@card_number

     WHILE @@FETCH_STATUS = 0
     begin
      if @total_mileage1>=40000 update belong set grade='银' where card_number=@card_number
        if @total_mileage1>=80000 update belong set grade='金' where card_number=@card_number
        if @total_mileage1>=160000 update belong set grade='白金' where card_number=@card_number

     FETCH NEXT FROM mycur
     INTO @total_mileage1,@card_number
     end


     CLOSE mycur
     DEALLOCATE mycur

     

    2009年12月7日 5:59
  • 很可惜 问题依旧

    2009年12月7日 10:00
  • 1、if @total_mileage1>=40000 update belong set grade='银' where card_number=@card_number
    2、if @total_mileage1>=80000 update belong set grade='金' where card_number=@card_number 
    3、if @total_mileage1>=160000 update belong set grade='白金' where card_number=@card_number

    如果@total_mileage1>=160000的话1、2、3步骤都会执行,这样就不好了。
    2009年12月7日 11:25