zoukankan      html  css  js  c++  java
  • 关于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 @field1=@table1_field1  --可能会根据其他跨表的结果更新当前值
      END  
      
      --最后根据主键更新相关值
      UPDATE xxx 
         SET field1=@field1,
             field2=@field2
       WHERE PrimaryKey=@PrimaryKey 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

  • 相关阅读:
    mybatis入门截图三
    centos 6.X 关闭selinux
    安装完最小化 RHEL/CentOS 7 后需要做的 30 件事情(二)
    安装完最小化 RHEL/CentOS 7 后需要做的 30 件事情(一)
    Linux定时任务Crontab命令详解
    CentOS 更换yum源为aliyun yum源
    CentOS7 FTP服务搭建(虚拟用户访问FTP服务)
    CentOS 7 安装Oracle 11gR2
    印度项目质量管理经验
    项目管理系列之质量管理
  • 原文地址:https://www.cnblogs.com/toSeeMyDream/p/4242337.html
Copyright © 2011-2022 走看看