• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
thankgoodness
博客园    首页    新随笔    联系   管理    订阅  订阅

SQL 同时操作多行记录时 触发器 问题

方法一

在delete触发器中可以使用deleted表(虚表),这个表有本次操作删除的所有记录,结构与原表一样。

在update触发器中可以使用inserted和deleted 2个表. 其中deleted有update前的记录数据,inserted有有update后的记录数据。

----
CREATE TABLE Class
(
ClassID int identity(1,1),
ClassName nvarchar(50)
)

CREATE TABLE Student
(
StudentID int identity(1,1),
StudentName nvarchar(50),
ClassID int
)

----
DECLARE @I INT
DECLARE @J INT
SET @I=1

WHILE @I<=10 BEGIN

INSERT INTO Class(ClassName) VALUES(CAST(@I AS nvarchar(50)))

SET @J=1
WHILE @J<=5 BEGIN

   INSERT INTO Student(StudentName,ClassID) VALUES(CAST(@J AS nvarchar(50)),CAST(@I AS nvarchar(50)))
   SET @J=@J+1
END
SET @I=@I+1

END

----
SELECT * FROM Class
SELECT * FROM Student

----
CREATE TRIGGER TDeleteStudents ON Class
FOR DELETE
AS

BEGIN TRAN Tran1

SAVE TRAN Point1

DELETE FROM Student WHERE ClassID IN (SELECT ClassID FROM deleted)

IF @@error <> 0
ROLLBACK TRAN Point1

COMMIT TRAN Tran1

GO

----TEST
DELETE FROM Class WHERE ClassID<=3

方法二

调用存储过程,使用游标代替触发器。例子如下:

/* 增/减文章,然后对发表用户加分/扣分,
   如果是回复,还需要处理对应主题的回复数 */

ALTER PROCEDURE [dbo].[spSetScore]
@strOptions nvarchar(100)=NULL,
@strWhere nvarchar(2000)=NULL,
@TopicID int=NULL

AS
BEGIN

DECLARE @intTopicID int
DECLARE @intUserID int
DECLARE @intParentTopicID int
DECLARE @intPointAddMaster int
DECLARE @intPointAddReplay int
DECLARE @intPointDelMaster int
DECLARE @intPointDelReplay int
DECLARE @Sql nvarchar(2000)


/* 删除时 @strWhere传没有带'where'的条件*/
IF @strOptions='DEL' AND NOT @strWhere IS NULL AND @strWhere!='' BEGIN

SELECT @intPointDelMaster=Score FROM BBSRuleTypes WHERE RuleType='A'--删除主题分数  
SELECT @intPointDelReplay=Score FROM BBSRuleTypes WHERE RuleType='R'--删除回复分数

/* 把删除的文章数据存储到临时表
SET @Sql=N'
    SELECT
     TopicID,
     UserID,
     ParentTopicID
    INTO #tempTable
    FROM BBSTopics WHERE ' + @strWhere
*/

CREATE TABLE #tempTable
(
   TopicID int,
   UserID int,
   ParentTopicID int
)
SET @Sql=N'
    INSERT INTO #tempTable
    SELECT
     TopicID,
     UserID,
     ParentTopicID
    FROM BBSTopics WHERE ' + @strWhere
EXEC(@Sql)

--定义游标
DECLARE CoursorTopic SCROLL CURSOR FOR
SELECT TopicID, UserID, ParentTopicID FROM #tempTable FOR READ ONLY
OPEN CoursorTopic
FETCH FROM CoursorTopic INTO @intTopicID,@intUserID,@intParentTopicID

/* 通过游标循环从临时表中逐条取出数据进行处理 */

WHILE @@fetch_status=0 BEGIN
  
   /*===============删除时 更新用户文章数量 /积分 / 等级 ================*/

   IF(@intParentTopicID=0 OR @intParentTopicID IS NULL) BEGIN --没有父ID,即删除主题

    UPDATE Users   
    SET TopicCount=TopicCount - 1,
     Point=Point - @intPointDelMaster,
     GradeID=(SELECT GradeID FROM BBSGrades WHERE DownLimit<=Point + @intPointDelMaster AND UpLimit>Point + @intPointDelMaster)
    FROM Users
    WHERE
UserID=@intUserID
   END
   ELSE BEGIN --删除回复贴子

    UPDATE Users   
    SET TopicCount=TopicCount - 1,
     Point=Point - @intPointDelReplay,
     GradeID=(SELECT GradeID FROM BBSGrades WHERE DownLimit<=Point + @intPointDelReplay AND UpLimit>Point + @intPointDelReplay)
    FROM Users
    WHERE
UserID=@intUserID

    --修改回复文章数
    UPDATE BBSTopics SET ResponseCount = ResponseCount-1 WHERE TopicID = @intParentTopicID
   END

   /* 继续取数据 */
   FETCH FROM CoursorTopic INTO @intTopicID,@intUserID,@intParentTopicID
END

CLOSE CoursorTopic

--删除临时表
DROP TABLE #tempTable
END

/* 添加时 @strWhere传TopicID */
IF @strOptions='ADD' AND (NOT @TopicID IS NULL AND @TopicID!=0) BEGIN

SELECT
   @intTopicID=TopicID,
   @intUserID=UserID,
   @intParentTopicID=ParentTopicID
FROM BBSTopics
WHERE
TopicID=@TopicID

/*===============更新时 更新用户文章数量 /积分 / 等级 ================*/
IF(@intParentTopicID=0 OR @intParentTopicID IS NULL) BEGIN --没有父ID,即发表新主题

   --添加主题分数
   SELECT @intPointAddMaster=Score FROM BBSRuleTypes WHERE RuleType='A'

   UPDATE Users   
   SET TopicCount=TopicCount + 1,
    Point=Point + @intPointAddMaster,
    GradeID=(SELECT GradeID FROM BBSGrades WHERE DownLimit<=Point + @intPointAddMaster AND UpLimit>Point + @intPointAddMaster)
   FROM Users
   WHERE
UserID=@intUserID
END
ELSE BEGIN --回复贴子
  
   --添加回复分数
   SELECT @intPointAddReplay=Score FROM BBSRuleTypes WHERE RuleType='R'

   UPDATE Users   
   SET TopicCount=TopicCount + 1,
    Point=Point + @intPointAddReplay,
    GradeID=(SELECT GradeID FROM BBSGrades WHERE DownLimit<=Point + @intPointAddReplay AND UpLimit>Point + @intPointAddReplay)
   FROM Users
   WHERE
UserID=@intUserID

   --修改回贴数
   UPDATE BBSTopics SET ResponseCount = ResponseCount+1 WHERE TopicID = @intParentTopicID
END

END


END

posted @ 2008-05-27 12:45  宇晨  阅读(872)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3