请教怎么写这样的一个触发器

huahaoyueyuan 2003-09-12 03:32:31
表rk 字段如下[id] ,[xjname] ,[jhnum],[rknum],[jiawei]
表kcb 字段如下[id] ,[xjname] ,[jhnum],[rknum],[jiawei]

当我向表rk 插入一条记录时启动触发器,检查kcb里是否有相同的xjnum(rk.jhnum=kcb.jhnum) ,如果有则kcb.rknum=kcb.rknum+rk.rknum (rknum是刚插入的值)没有则插入一条新的记录
CREATE TRIGGER TEST ON rk
FOR INSERT
AS
BEGIN
IF EXISTS (SELECT 1 FROM kcb, INSERTED B WHERE kcb.xjname=B.xjname)
UPDATE kcb SET kcb.rknum=kcb.rknum+B.rknum FROM INSERTED B WHERE B.xjname=kcb.xjname
ELSE
INSERT INTO kcb(xjname,jhnum,rknum,jiawei)
SELECT A.xjname,A.rknum FROM INSERTED A LEFT JOIN kcb B ON B.xjname = A.xjname

END
执行这触发器写出的rknum根本不对,我输入的rknum=9,kcb表里没有相同的记录
那么kcb里的rknum也应是9可执行出来的是27为什么,我是刚会SQL SERVER
帮忙写点注释好吗,我看不太懂 

...全文
45 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
huahaoyueyuan 2003-09-12
  • 打赏
  • 举报
回复
同志们帮帮呀,你们写的,我动行结没有一个是对的,全部是执行两遍,我快晕了,到底错在
什么地方
lcq9732 2003-09-12
  • 打赏
  • 举报
回复
CREATE TRIGGER TEST ON rk
FOR INSERT
AS
BEGIN
IF EXISTS (SELECT 1 FROM kcb WHERE kcb.xjname=(select xjname from INSERTED))
UPDATE kcb SET kcb.rknum=kcb.rknum+(select rknum from INSERTED) WHERE xjname=(select xjname from INSERTED)
ELSE
INSERT INTO kcb(xjname,jhnum,rknum,jiawei)
SELECT xjname,jhnum,rknum,jiawei FROM INSERTED
lfengxu 2003-09-12
  • 打赏
  • 举报
回复
虚拟表Inserted 虚拟表Deleted
在表记录新增时 存放新增的记录 不存储记录
修改时 存放用来更新的新记录 存放更新前的记录
删除时 不存储记录 存放被删除的记录

触发器的种类及触发时机
After触发器:触发时机在资料已变动完成后,它将对变动资料进行必要的
善后与处理,若发现有错误,则用事务回滚(Rollback Transaction)
将此次操作所更动的资料全部回复。
Istead of 触发器:触发时机在资料变动前发生,且资料如何变动取决于触发器
现在介绍一下创建触发器的编写格式:
After类型:
Create Trigger 触发器名称
on 表名
after 操作(insert,update)
as
Sql语句
Instead类型
Create Trigger 触发器名称
on 表名
Instead of 操作(update,delete)
as
Sql语句
实例1:
在订单(表orders)中的订购数量(列名为num)有变动时,触发器会先到客户(表Customer)中
取得该用户的信用等级(列名为Level),然后再到信用额度(Creit)中取出该级
许可的订购数量上下限,最后比较订单中的订购数量是否符合限制。
代码:
Create Trigger num_check
on orders
after insert,update
as
if update(num)
begin
if exists(select a.* from orders a join customer b on a.customerid=b.customerid
join creit c on b.level=c.level
where a.num between c.up and c.down)
begin
rollback transaction
exec master..xp_sendmail 'administrator','客户的订购数量不符合限制'
end
end
实例2:
有工资管理系统中,当公司对某员工甲的月薪进行调整时,通常会先在表员工中修改薪资列,然后在表员工记录中修改薪资调整时间与薪资
Create trigger compensation
on 员工
after update
as
if @@rowcount=0 return
if update(薪资)
begin
insert 员工记录
select 员工遍号,薪资,getdate()
from inserted
end
lfengxu 2003-09-12
  • 打赏
  • 举报
回复
CREATE TRIGGER TEST ON rk
FOR after INSERT
AS
declare @aaa varchar(50)
BEGIN
INSERT INTO kcb(xjname,jhnum,rknum,jiawei)
SELECT A.xjname,A.jhnum,0,A.jiawei
FROM INSERTED A LEFT JOIN kcb B ON B.xjname = A.xjname
WHERE B.xjname is null

UPDATE kcb SET kcb.rknum=kcb.rknum+B.rknum
FROM INSERTED B WHERE B.xjname=kcb.xjname
END
huahaoyueyuan 2003-09-12
  • 打赏
  • 举报
回复
这样写不对,执行结果跟我写在上面的程序执行的一样,我在rk表里插入的是10可在
kcb里显示的却是20为什么
yujohny 2003-09-12
  • 打赏
  • 举报
回复
我的思路:先插入没有的数据,将rknum设为零
然后再一次更新
yujohny 2003-09-12
  • 打赏
  • 举报
回复
CREATE TRIGGER TEST ON rk
FOR INSERT
AS
BEGIN
INSERT INTO kcb(xjname,jhnum,rknum,jiawei)
SELECT A.xjname,A.jhnum,0,A.jiawei
FROM INSERTED A LEFT JOIN kcb B ON B.xjname = A.xjname
WHERE B.xjname is null

UPDATE kcb SET kcb.rknum=kcb.rknum+B.rknum
FROM INSERTED B WHERE B.xjname=kcb.xjname
END

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧