在程序中实现,先更新student表,再删除party表
1.update student set partyname='' where ...
2.delete party where ...

解决方案 »

  1.   

    因为你建立了外键。Createt Trigger tr_de On party 
    after Delete
    As
    Declare @partyname Varchar(50)
    Select @partyname=partyname From deleted
    If Exists(Select * From student Where partyname =@partyname)
          Update student Set partyname='' Where partyname=@partyname
      

  2.   

    --改为Before触发器
    Createt Trigger tr_de On party 
    Before Delete
    As
    Declare @partyname Varchar(50)
    Select @partyname=partyname From deleted
    If Exists(Select * From student Where partyname =@partyname)
          Update student Set partyname='' Where partyname=@partyname
    Delete From partyname Where partyname =@partyname
      

  3.   

    回复: outwindows(窗外) 
    在程序中我比较难处理。
    我处理delphi中的。before delete.事件好像不行。感觉这个机理和触发器的一样。
    可能只能在adoquery1.delete值钱判断了。弄个事务是最好的办法。
    ----------------------------
    回复: Frewin(Frewin) ( ) 
    这种方法不行。我试过来。好像在oracle里面有删除前触发的事件。在
    sqlserver2000里面看了帮助没有这个事件。
    ---------------------------
    回复: Frewin(Frewin) 
    好像没有这个before触发器。
    在oracle里面有
      

  4.   

    按照你的设计,你可以去除这个主外键关系,然后用触发器来实现业务规则
    或者可以是用instead of 触发器,但同样也会有一个问题,那就是更新为null或''后,会有主键参照吗?
      

  5.   

    如果设置了外键约束,删除的触发器应该用 instead of ,并且要在该触发器中重新发出删除主表记录的删除语句.
      

  6.   

    回复: zheninchangjiang(徐震>愿母亲安息) 
    意思就是说:触发器这条路就走不通了。
    只能在客户端程序中来执行了?
      

  7.   

    to: zjcxc(邹建) ( 
    但是这里有个问题。
    我要获得删除的字段值,只能到deleted.fields去取得。
    既然是deleted.fields,那么这个记录已经是 被删除掉放到缓存里面去了。
    instead of 这个看看帮助好像很难理解
      

  8.   

    to: zjcxc(邹建) ( ) 信誉:349 
    太感谢了!!!
    我原本以为很容易实现。这个问题也很常见。也许我得表设置得不是很妥当。
    后来结果弄了半天。还是没有眉目。
      

  9.   

    to:zheninchangjiang(徐震>愿母亲安息) ( ) 信誉:100 
    如果按照这个:
    按照你的设计,你可以去除这个主外键关系,然后用触发器来实现业务规则
    我感觉:如果这样做地话,还是在客户端用个事务改改方便。
      

  10.   

    to:zheninchangjiang(徐震>愿母亲安息) ( ) 信誉:100 
    如果按照这个:
    按照你的设计,你可以去除这个主外键关系,然后用触发器来实现业务规则
    我感觉:如果这样做地话,还是在客户端用个事务改改方便。不管是客户端还是服务器端,都要受主外键关系的约束,你要先改为null或是'',同样受主键的约束,
    如果是我,我喜欢用触发器,这样在客户端的处理要简单一点
      

  11.   

    --测试表create table party(partyname varchar(10) primary key,memo varchar(10))
    create table student(no int,name varchar(10),partyname varchar(10),memo varchar(10)
    ,constraint FK_student_party foreign key(partyname) references party(partyname)
    ON UPDATE CASCADE --级联更新
    ON DELETE NO ACTION --删除约束
    )
    go--测试数据
    insert party select '1','aa'
    union  all   select '2','bb'insert student select 1,'11','1','--'
    union  all     select 1,'12','1','--'
    union  all     select 2,'22','2','--'
    go--创建删除处理的触发器
    create trigger tr_delete on party
    instead of delete  --如果设置了外键约束,则触发器类型必须是此种
    as
    select * from deleted  --这句演示是否触发了触发器--重新发出删除命令
    delete a from party a 
    where exists(select 1 from deleted where partyname=a.partyname)--更新 student
    update a set partyname=''
    from student a
    where exists(select 1 from deleted where partyname=a.partyname)
    go--删除
    delete from party where partyname='1'
    select * from party
    select * from student
    go--删除测试
    drop table student,party
      

  12.   

    不是。如果是null的话是没有问题的。
    ''可能是有问题。但是我没有测试过。不敢乱说。
      

  13.   

    上面是我的测试,证实了我的说法: "设置了外键约束的话,楼主的删除应该根本不可能成立"
    所以,结论就一个:
    如果是两个表的 partyname 之间有外键约束关系的话,楼主的功能根本不能实现,因为这种要求违反了外键约束的规定
    所以无论在程序中,还是在数据库中,都实现不了.
      

  14.   

    看了一下测试结果是这样子的:(所影响的行数为 2 行)
    (所影响的行数为 3 行)
    (所影响的行数为 1 行)服务器: 消息 547,级别 16,状态 1,过程 tr_delete,行 9
    DELETE 语句与 COLUMN REFERENCE 约束 'FK_student_party' 冲突。该冲突发生于数据库 'test',表 'student', column 'partyname'。
    语句已终止。
      

  15.   

    to: zjcxc(邹建) ( ) 信誉:349 
    上面是我的测试,证实了我的说法: "设置了外键约束的话,楼主的删除应该根本不可能成立"
    所以,结论就一个:
    如果是两个表的 partyname 之间有外键约束关系的话,楼主的功能根本不能实现,因为这种要求违反了外键约束的规定
    所以无论在程序中,还是在数据库中,都实现不了.
    -----------------------------------------------------
    看来我的数据库设计得有点问题。。
      

  16.   

    --更新为null可以,不能更新为''--更新为null的话,触发器写成这样(我上面的测试忽略了删除顺序)create trigger tr_delete on party
    instead of delete
    as
    --更新 student
    update a set partyname=null
    from student a
    where exists(select 1 from deleted where partyname=a.partyname)--重新发出删除命令
    delete a from party a 
    where exists(select 1 from deleted where partyname=a.partyname)
    go
      

  17.   

    --测试表create table party(partyname varchar(10) primary key,memo varchar(10))
    create table student(no int,name varchar(10),partyname varchar(10),memo varchar(10)
    ,constraint FK_student_party foreign key(partyname) references party(partyname)
    ON UPDATE CASCADE --级联更新
    ON DELETE NO ACTION --删除约束
    )
    go--测试数据
    insert party select '1','aa'
    union  all   select '2','bb'insert student select 1,'11','1','--'
    union  all     select 1,'12','1','--'
    union  all     select 2,'22','2','--'
    go--创建删除处理的触发器
    create trigger tr_delete on party
    instead of delete
    as--更新 student
    update a set partyname=null
    from student a
    where exists(select 1 from deleted where partyname=a.partyname)--重新发出删除命令
    delete a from party a 
    where exists(select 1 from deleted where partyname=a.partyname)
    go--删除
    delete from party where partyname='1'
    select * from party
    select * from student
    go--删除测试
    drop table student,party
    /*--测试结果partyname  memo       
    ---------- ---------- 
    2          bb(所影响的行数为 1 行)no          name       partyname  memo       
    ----------- ---------- ---------- ---------- 
    1           11         NULL       --
    1           12         NULL       --
    2           22         2          --(所影响的行数为 3 行)
    --*/
      

  18.   

    oracle好像是可以实现得。
    有触发前和触发后之分。(听人说)
    看来大型和中型数据库是有区别得
      

  19.   

    --不是已经告诉你了,sql中也有,我上面不是已经帮你写出来了吗?create trigger tr_delete on party
    instead of delete  --就这种,前置触发器
    as