不好意思刚才写错了
tb1有两个字段a int 和 b nchar(10). 现在我在tb1上建了个触发器trig_tb1如下create trigger trig_tb1 on tb1 instead of delete as 
delete tb1 from tb1,deleted where tb1.a=deleted.a and tb1.b=deleted.b ----这句不会错 
select * into temp_tb1 from deleted 
exec('delete tb1 from tb1,temp_tb1 where tb1.a=temp_tb1.a and  tb1.b=temp_tb1.b')---这样写就报错了
当向表里插入数据时报错:INSTEAD OF triggers do not support direct recursion. The trigger execution failed.
目的:
 要把tb1里和 deleted数据一样的数据删除。
 这个是用在数据同步软件里的触发器代码,事先不知道要删除什么数据。
 在真实应用中 delete 语句比较复杂是一个字符串通过deleted表获得要删除的数据,在exec里执行。
自己的理解与想法
我目前自己了解的意思,好像trigger不支持递归调用,我设置了RECURSIVE_TRIGGERS,nested_triggers这两个参数还是报同样的错误。
语句如下
        ALTER DATABASE test2 SET RECURSIVE_TRIGGERS on
        EXEC   sp_configure  'nested_triggers',    1
        RECONFIGURE   WITH        OVERRIDE    我的想法:是不是有什么能够使exec()执行的时候不让它触发触发器呢?在exec里禁用触发器,执行完delete后再启用,这种方法是可行,但是问题提示执行exec的时候禁用了触发器,外面再有删除操作的时候,触发器就不起作用了。苦恼啊!不知道哪位大侠有好的思路。
 

解决方案 »

  1.   

    沒有判斷表的是否存在select * into temp_tb1 from deleted 
    exec('delete tb1 from tb1,temp_tb1 where tb1.a=temp_tb1.a and  tb1.b=temp_tb1.b')這是寫法有錯,把 這兩判斷 
      

  2.   


     我的想法:是不是有什么能够使exec()执行的时候不让它触发触发器呢?在exec里禁用触发器,执行完delete后再启用,这种方法是可行,但是问题提示执行exec的时候禁用了触发器,外面再有删除操作的时候,触发器就不起作用了。苦恼啊!不知道哪位大侠有好的思路。都BL放在程序去實現,儘量少用觸發器
      

  3.   

    试了几遍只有这样可以if object_id('tb1')is not null drop table tb1
    go
    create table tb1
    (
        a int ,
        b varchar(50)
    )
    go
    insert tb1
    select 1,'AA' union all 
    select 2,'BB' union all 
    select 3,'CC' union all 
    select 4,'DD'
    go
    if object_id('trig_tb1')is not null drop trigger trig_tb1
    go
    create trigger trig_tb1 on tb1 instead of delete as 
    delete tb1 from tb1,deleted where tb1.a=deleted.a and tb1.b=deleted.b ----这句不会错 
    select * into #temp_tb1 from deleted exec('alter table tb1 DISABLE TRIGGER trig_tb1 
    delete tb1 from tb1,#temp_tb1 where tb1.a=#temp_tb1.a and  tb1.b=#temp_tb1.b
    alter table tb1 enable TRIGGER trig_tb1 ')---这样写就报错了
    delete tb1 where a=1select * from tb1
      

  4.   

     6 楼 xys_777 的这种方法我也试过了,exec的时候禁用了触发器,外面再有删除操作的时候,触发器就不起作用了。苦恼啊!
      

  5.   

    exec('alter table tb1 DISABLE TRIGGER trig_tb1 
    delete tb1 from tb1,#temp_tb1 where tb1.a=#temp_tb1.a and  tb1.b=#temp_tb1.b
    alter table tb1 enable TRIGGER trig_tb1 ')alter table tb1 DISABLE TRIGGER trig_tb1 了,触发器禁用了,所以这个时候触发器外有删除tb1的动作,触发器就不起作用了(因为禁用了啊),只有当enable了之后,触发器才重新起作用!
      

  6.   

    exec('alter table tb1 DISABLE TRIGGER trig_tb1 
    delete tb1 from tb1 with(tablock,xlock),#temp_tb1 where tb1.a=#temp_tb1.a and  tb1.b=#temp_tb1.b
    alter table tb1 enable TRIGGER trig_tb1 ')那就得先锁上