zoukankan      html  css  js  c++  java
  • SQL触发器学习

     

    简介

    触发器是一种特殊类型的存储过程。触发器分为:

    DML( 数据操纵语言 Data Manipulation Language)触发器:数据库中表或视图的数据更改时触发,包括insert,update,delete语句

    DDL(数据定义语言 Data Definition Language)触发器:表或索引中的create、alter、drop语句。

    登陆触发器:是指当用户登录SQL SERVER实例建立会话时触发。

     

    优劣

    可以强制执行业务规则:

    Microsoft SQL Server™ 2000 提供了两种主要机制来强制业务规则和数据完整性:约束和触发器。触发器可以强制比用 CHECK 约束定义的约束更为复杂的约束。比

    如触发器可通过数据库中的相关表实现级联更改,也可以评估数据修改前后的表状态,并根据其差异采取对策。

    以事件方式来处理:当数据发生变化的时候,自动处理

     

    缺点

    当数据库之间导入导出的时候,可能会引起不必要的触发逻辑

    移植性差

    触发器只能在当前的数据库中创建,但是可以引用当前数据库的外部对象。

    CREATE TRIGGER 必须是批处理中的第一条语句,并且只能应用于一个表。

    如果一个表的外键包含对定义的 DELETE/UPDATE 操作的级联,则不能对为表上定义 INSTEAD OF DELETE/UPDATE 触发器。

    虽然 TRUNCATE TABLE 语句实际上就是 DELETE 语句,但是它不会激活触发器,因为该操作不记录各个行删除。

     

    存贮速度和执行速度:

    代码是存储在服务器上, 执行速度主要取决于 数据库服务器的性能与触发器代码的复杂程度。

    下面重点说下DML触发器。其它的资料请参考MSDN: http://msdn.microsoft.com/zh-cn/library/ms189799.aspx

    语法

    DML触发器语法定义:

    CREATE TRIGGER [ schema_name . ]trigger_name

    ON { table | view }

    [ WITH <dml_trigger_option> [ ,...n ] ]

    { FOR | AFTER | INSTEAD OF }

    { [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] }

    [ WITH APPEND ]

    [ NOT FOR REPLICATION ]

    AS

    { sql_statement [ ; ] [ ,...n ] | EXTERNAL NAME <method specifier [ ; ] > }

    DML 触发器使用 deleted 和 inserted 逻辑(概念)表。 它们在结构上类似于定义了触发器的表,即对其尝试执行了用户操作的表。 在 deleted 和 inserted 表保存了可能会被用户更改的行的旧值或新值。获取值可用sql'select * from inserted'.

     

    Insert

    update

    delete

    Deleted表

    旧值

    旧值

    Inserted表

    新值

    新值

     

    示例

     

    Insert触发器

    --判断触发器是否存在

    IF ( OBJECT_ID('TR_Class_Create', 'tr') IS NOT NULL )

    DROP TRIGGER TR_Class_Create

    GO

    --创建Create触发器

    CREATE TRIGGER TR_Class_Create ON dbo.Class

    FOR INSERT

    AS

    --义变量

    DECLARE @classname_new NVARCHAR(50);

    --获取新的班级名称

    SELECT @classname_new = ClassName

    FROM inserted;

    --验证是否已存在

    IF ( EXISTS ( SELECT *

    FROM dbo.Class

    WHERE ClassName =@classname_new) )

    BEGIN

    RAISERROR('名称已存在',16,1);--抛出一个错误

    ROLLBACK TRAN;--事物回滚

    END

    GO

    --===================================================================

    --判断触发器是否存在

    IF ( OBJECT_ID('TR_Class_Update', 'tr') IS NOT NULL )

    DROP TRIGGER TR_Class_Update

    GO

    --创建Update触发器

    CREATE TRIGGER TR_Class_Update ON dbo.Class

    FOR UPDATE

    AS

    --列级别:判断某列是否更新

    IF ( UPDATE(ClassName) )

    BEGIN

    --定义变量

    DECLARE @classname_new NVARCHAR(50) ,

    @classname_old NVARCHAR(50);

    SELECT @classname_new = ClassName

    FROM inserted;--获取新的班级名称

    SELECT @classname_old = ClassName

    FROM deleted;--获取旧的班级名称

    --级联更新

    UPDATE dbo.Student

    SET ClassName = @classname_new

    WHERE ClassName = @classname_old

    END

    GO

    --===================================================================

    --判断触发器是否存在

    IF ( OBJECT_ID('TR_Class_Delete', 'tr') IS NOT NULL )

    DROP TRIGGER TR_Class_Delete

    GO

    --创建Delete触发器

    CREATE TRIGGER TR_Class_Delete ON dbo.Class

    FOR UPDATE

    AS

    --备份数据-判断备份表是否存在

    IF ( OBJECT_ID('ClassBackup', 'U') IS NOT NULL )

    BEGIN

    --数据备份

    INSERT INTO ClassBackup SELECT * FROM DELETED;

    END

    ELSE

    --不存在则创建

    SELECT *

    INTO ClassBackup

    FROM DELETED;

     

    GO

     

    --===================================================================

    --触发器查询

    --查询数据库所有触发器

    select * from sysobjects where xtype='TR'

    select * from sys.triggers;

    --查看触发器触发事件

    select te.* from sys.trigger_events te join sys.triggers t

    on t.object_id = te.object_id

    where t.parent_class = 1 and t.name = 'TR_Class_Create';

    --查看单个触发器

    exec sp_helptext 'TR_Class_Create'

    --禁用触发器

    disable trigger TR_Class_Create on student;

    --启用触发器

    enable trigger TR_Class_Create on student;

    --删除触发器

    drop trigger TR_Class_Create

     

    结束语

    触发器偶尔用用还是能解决大问题的,使实现更简洁。初步学习,如有错误,欢迎指正。

  • 相关阅读:
    php 三元运算符简洁用法
    Linux 获取网卡信息
    《构建之法》读后感
    毫秒数据字符串转换为DateTime
    POST请求——HttpWebRequest
    多个不同类对象传输思路
    WCF 大文件传输配置
    WCF配置文件详解
    C# 元组、匿名对象、ref&out
    C#控制台关闭之前做一些操作
  • 原文地址:https://www.cnblogs.com/lipanpan/p/3849326.html
Copyright © 2011-2022 走看看