关于SQLServer2000中触发器的使用——多行数据提交

关于触发器的使用,有很多争议。
触发器的好处不言而喻是增强了数据的校验能力,能够有效地实现复杂的业务逻辑。在一定程度上走的比约束和check走的更远。
关于触发器的坏处,最典型的就是触发器的使用会导致系统性能下降,数据的不可控性,尤其是跨表检测,以及可能导致的触发器递归更加加深了数据的维护难度和不可控性。

本文无意讨论触发器的原理和好坏,旨在描述一个关于批量数据提交时的触发器是如何设计的。

SET QUOTED_IDENTIFIER ON 
GO
SET ANSI_NULLS ON 
GO

CREATE TRIGGER [TRI_xxx] ON xxx
FOR INSERT,UPDATE
AS
SET NOCOUNT ON

DECLARE 
--检测标志设置
  @CHECK INT,    
--定义公共变量 
  @TODAY DATETIME
--定义基表变量
  @field1 INT,
  @field2 INT,
  @field3 VARCHAR(20),
  @fieldN INT,
--定义跨表变量  
  @table1_field1 INT,
  @table1_field2 INT,
  @tableN_fieldM INT
--定义游标
  DECLARE cur_xxx CURSOR FOR
    SELECT field1,field2,field3,fieldN FROM INSERTED 
--如果非集合修改,则定义为如下
/*
SELECT @field1=field1,
       @field2=field2,
       @field3=field3,
       @field4=field4,
FROM INSERTED
*/

SET @TODAY=CONVERT(VARCHAR(10),GETDATE(),120)
  
  OPEN CUR_ZYGD
  FETCH NEXT FROM cur_xxx INTO @field1,@field2,@field3,@fieldN

WHILE (@@FETCH_STATUS=0) 
  BEGIN

------------------------------------------------------------------------
--------------------以下针对不同的规则,进行相关处理--------------------
------------------------------------------------------------------------

--满足某某条件,则不处理直接退出
  IF cond1
  BEGIN
    CLOSE cur_xxx             --非游标,无需该语句
    DEALLOCATE cur_xxx        --非游标,无需该语句
    RETURN
  END

--满足某某条件,则提示处理直接退出
  IF cond2
  BEGIN  
    RAISERROR(‘XXX错误!‘,16,1)
    ROLLBACK TRAN 
    CLOSE cur_xxx             --非游标,无需该语句
    DEALLOCATE cur_xxx        --非游标,无需该语句
    RETURN  
  END
  
--跨表检查,满足某某条件,则提示处理直接退出
  SELECT TOP 1 @table1_field1=field1 FROM table1 WHERE 1=1
  IF cond3 IS NOT NULL
  BEGIN
    RAISERROR(‘XXX错误!‘,16,1)
    ROLLBACK TRAN
    CLOSE cur_xxx            --非游标,无需该语句
    DEALLOCATE cur_xxx       --非游标,无需该语句
    RETURN  
  ELSE 
  BEGIN
    SET @[email protected]_field1  --可能会根据其他跨表的结果更新当前值
  END  
  
  --最后根据主键更新相关值
  UPDATE xxx 
     SET [email protected],
         [email protected]
   WHERE [email protected] AND (ISNULL(field1,‘‘)<>ISNULL(@field1,‘‘) OR ISNULL(field2,0)<>ISNULL(@field2,0))

FETCH NEXT FROM cur_xxx INTO @field1,@field2,@field3,@fieldN

END

CLOSE CUR_xxx
DEALLOCATE CUR_xxx

SET NOCOUNT OFF

GO
SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO

时间: 2024-10-13 06:54:41

关于SQLServer2000中触发器的使用——多行数据提交的相关文章

java中从控制台输入多行数据 按回车键输入空行结束

这篇博文是用Windows Live Writer写的,看看效果 下面是以前写的程序:java中从控制台输入多行数据 按回车键输入空行结束 //试过几个插件,发现插入代码后都不能复制, 但是插入图片还是很方便的, 用wlw写博客好处是可以离线, 以后就用wlw写,然后发布草稿,再到CSDN插入代码后发表文章,只是写个博客要这么艰难吗!!! <pre name="code" class="java">Scanner scanner = new Scanne

sqlserver中将行数据转为Xml文件格式

将sqlserver中的某张表中的行数据转为XML格式的文件的方法: 语法:select * from  表名   for xml path(xml文件中父节点的名称) 案例: //  在Movie数据库下创建一张用户基本信息表[UserInfoes]: USE [Movie]GOCREATE TABLE [dbo].[UserInfoes]( [userId] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY, [userName] [varchar](50)

mssql sqlserver 禁止删除数据表中指定行数据(转自:http://www.maomao365.com/?p=5323)

转自:http://www.maomao365.com/?p=5323 摘要:下文主要讲述,如何禁止删除数据表中指定行数据 最近收到用户一个需求,禁止所有人删除”表A”中,ID 为1.2.3.4.5的系统默认数据,通过项目组同事仔细研究,我们得到一致的答案为:在表上新增一个触发器,当删除数据ID为 1 2 3 4 5时候,直接弹出相应的错误,采用这种模式,可以限制所有端口的异常操作(程序 查询分析器),具体实现方式,如下文所示: create trigger trTriggerA on A fo

获取所有分组中某列最大的行

怎么获取所有分组中某列最大的行?下面用一个例子来说明下: 一共公司有若干员工,每个员工有各自的id, group_id(部门), salary(工资).现在的问题转变为 求公司各部门最高工资的员工 首先明确一个问题,一个部门的若干个员工可能同时拥有最高的工资,需要都列举出来. 看一下员工的数据库表结构(只包含有用的列): Field Type Null Key Default Extra id int(11) NO PRI NULL   group_id int(11) YES   NULL  

05. 取SQL分组中的某几行数据

原文:05. 取SQL分组中的某几行数据 对表中数据分组,有时只需要某列的聚合值:有时却需要返回整行数据,常用的方法有:子查询.ROW_NUMBER.APPLY,总体感觉还是ROW_NUMBER比较直观.测试数据: if OBJECT_ID('testGroup') is not null drop table testGroup GO create table testGroup ( ID int identity primary key, UserID int, OrderID int )

定位表中的行数据存放于哪一个具体的datafile上

副标题:用一个PL/SQL查出表中的行数据存放在哪个具体的datafile中 经常有遇到做DBA的朋友问,该如何知道自己插入的某一行数据,是存在了数据库中的哪一个数据文件(datafile)上了,回答是肯定可以的.在此,就将该方法写出来供更多的朋友使用. 1.正常查询步骤 1.1.先查到表上行数据的ROWID select rowid from tivoli.test_db_avg1 where rownum =1 输出值:   AAAQ0mAAEAAAAhLAAA 1.2.根据ROWID定位到

老男孩教育每日一题:2017年3月9日-请解释下面Shell脚本中if开头的整行代码的意思及应用场景吗?

请解释下面Shell脚本中 if开头的整行代码的意思,你见过它的应用场景么? if(kill -0 $pid 2>/dev/du11) then     echo"oldboy" else    echo"oldgirl" fi 面试题:请解释if (kill -0 $pid 2>/dev/null)代码的意思? if(kill -0 $pid 2>/dev/null)     then        echo "oldboy"

Linux 中常用的文本(行)处理命令(转)

Linux 中常用的文本(行)处理命令 0.正则表达式(regular expression) 元字符(如下图)是正则表达式中含有的字符,在正则表达式中可以在字符串中使用元字符以匹配字符串的各种可能的情况. 注意: (1) 在"[ ]"中还可以使用"-"来表示某一范围.例如"[a-z0-9]"匹配任意的小写字母或者数字,"[^A-Z]"表示非大写字母,"[0-9]{8}"表示任意一个8位数字. (2) 元字

获取GridView中RowCommand的当前索引行

原文:http://blog.csdn.net/sabty/article/details/4816160 获取GridView中RowCommand的当前索引行 前台添加一模版列,里面添加一个LinkButton 前台 (如果在后台代码中用e.CommandArgument取值的话前台代码就必须在按钮中设置CommandArgument的值,值为绑定的数据库字段 <asp:TemplateField HeaderText="操作"> <ItemTemplate>