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

insert into 批量插入, 触发器只响应最后一条数据,怎么办啊???
本帖最后由 Pc498471249 于 2013-03-28 15:54:24 编辑
这是触发器的代码

USE [QQData]
GO
/****** Object:  Trigger [dbo].[tgr_Tab_10000_Insert]    Script Date: 03/28/2013 15:20:43 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER  [dbo].[tgr_Tab_10000_Insert]
   ON  [dbo].[Tab_10000]
   for INSERT
AS 
BEGIN
SET NOCOUNT ON;
declare @RepeatCount int=0;
declare @Id int;
declare @QQNumber bigint;
declare @QQPassword varchar(1000);
select @Id=Id,@QQNumber=QQNumber,@QQPassword=QQPassword from Inserted;
select top 1 @RepeatCount=count(QQNumber) from Tab_10000 where QQNumber=@QQNumber;
if(@RepeatCount>1)
begin
/*更新*/
set @QQPassword='∝'+@QQPassword;
update Tab_10000 set QQPassword=QQPassword+@QQPassword where QQNumber=@QQNumber and Id<>@Id;
/*删除*/
delete from Tab_10000 where Id=@Id;
end
END



insert into Tab_10000(QQNumber,QQPassword)
select 1000004,'我草草草哈哈' union
select 1000004,'我草草草哈哈' union
select 1000003,'哈哈哈嘿嘿' union
select 1000003,'123456'

select * from tab_10000

这是测试批量插入的代码

本来应该是 
1000003 哈哈哈嘿嘿∝123456
1000004 我草草草哈哈∝我草草草哈哈

只有1000003响应触发器了, 1000004没有响应,直接插入新数据了, 这是怎么回事, 难道触发器不能处理批量插入么????

------解决方案--------------------
引用:
select @Id=Id,@QQNumber=QQNumber,@QQPassword=QQPassword from Inserted;

这句话错了,你不能假设inserted只有一行记录
------解决方案--------------------
详情参考MSDN:
DML 触发器的多行注意事项
------解决方案--------------------
引用:
引用:select @Id=Id,@QQNumber=QQNumber,@QQPassword=QQPassword from Inserted;
这句话错了,你不能假设inserted只有一行记录


高见。你这里得用游标去一条条的取然后去更新。。。
------解决方案--------------------
你不会用游标就别用游标,有游标必须遵循一个原则——游标遍历过程中不得出现SELECT语句。这也包括调用的函数中也不能出现SELECT语句,否则就别用游标。做不到这点的,就是不会用游标的,这也是大多数人使用游标只会让速度变慢的最大原因。
------解决方案--------------------
引用:
引用:你不会用游标就别用游标,有游标必须遵循一个原则——游标遍历过程中不得出现SELECT语句。这也包括调用的函数中也不能出现SELECT语句,否则就别用游标。做不到这点的,就是不会用游标的,这也是大多数人使用游标只会让速度变慢的最大原因。
我不用select语句如何实现我的逻辑

select语句合并到游标定义中去,比如你这里定义的游标SQL是这样的:
select Id,QQNumber,QQPassword from inserted;
而游标中出现了这条:
select top 1 @RepeatCount=count(QQNumber) from Tab_'+CONVERT(varchar(5),@begin)+' where QQNumber=@QQNumber;
那么你就要考虑将这2条SQL语句并为一条:
declare cur_insert cursor for
select a.Id,a.QQNumber,a.QQPassword,b.RepeatCount from inserted a left join (SELECT QQNumber,COUNT(1) RepeatCount FROM Tab_10000 GROUP BY QQNumber) b on a.QQNumber = b.QQNumber;

如此一来,你需要的RepeatCount也有了,遍历游标过程中也不用出现SELECT语句了。

当然这种通过触发器处理的设计本身是否合理我不就发言了,我不想讨论的过分深入,这里只是针对游标画龙点睛,点到为止。