目录
一、触发器概念
二、触发器优缺点
2.1优点:
2.2缺点:
三、触发器种类
四、触发器创建
4.1创建DML触发器
4.2创建DDL触发器
4.3创建登录触发器
五、触发器管理
5.1查看触发器
5.1.1.使用sp_helptext存储过程查看触发器
5.1.2.获取数据库中触发器的信息
5.2修改触发器
5.2.1修改DML触发器
5.2.2修改DDL触发器
5.2.3修改登录触发器
5.3重定名触发器
5.4禁用与启用触发器
5.4.1禁用触发器
5.4.2启用触发器
5.5删除触发器
5.5.1.DROP TRIGGER语句删除触发器
5.5.2.SQL Server Management Studio手动删除触发器
六、触发器应用场景
一、触发器概念
Microsoft SQL Server提供两种重要机制来欺压使用业务规则和数据完整性,即束缚和触发器。
触发器是一种特殊范例的存储过程,当指定表中的数据发生变革时触发器主动生效。它与表紧密
相连,可以看作是表界说的一部分。触发器不能通过名称被直接调用,更不答应设置参数。
触发器是一种特殊范例的存储过程,它会在数据库表中的数据发生特定事件时主动实行。这些事件可以是数据的插入、更新或删除利用。触发器可以用于实现数据完整性、业务规则和复杂的数据处理逻辑。
触发器由两部分组成:触发事件和触发利用。
触发事件界说了何时触发触发器,可以是在数据插入、更新或删除之前或之后触发。触发利用是在触发事件发生时实行的一系列 SQL 语句。
触发器可以与特定的表相关联,并在关联表的数据发生更改时实行。它们可以用于欺压实行特定的业务规则,例如束缚条件、数据验证和引用完整性。触发器还可以用于日志记载、审计和数据同步等任务。它们答应开发人员跟踪和控制数据库中的利用,以确保数据的同等性和正确性。
SQL Server 2008 支持多个触发器范例,包罗:
- 插入触发器(INSERT Trigger):在向表中插入新行之前或之后触发。
- 更新触发器(UPDATE Trigger):在更新表中的行之前或之后触发。
- 删除触发器(DELETE Trigger):在从表中删除行之前或之后触发。
- 合并触发器(MERGE Trigger):在实行 MERGE 语句时触发。
在SQL Server中一张表可以有多个触发器,每个表最多可以有一个触发器与每种触发事件相关联。也就是对于每个表,最多可以界说三个触发器,分别是一个插入触发器、一个更新触发器和一个删除触发器:
- INSERT触发器:当在表中插入新行时触发。
- UPDATE触发器:当在表中更新现有行时触发。
- DELETE触发器:当从表中删除行时触发。
用户可以使用NSERT、UPDATE或DELETE语句对触发器举行设置,也可以对一张表上的特定利用设置多个触发器。触发器可以包含复杂的Transact-SQL语句。不论触发器所举行的利用有多复杂,触发器都只作为一个独立的单元被实行,被看作是一个事务。假如在实行触发器的过程中发生了错误,则整个事务将会主动回滚。
但是每个触发器范例只能与表的对应事件相关联,不答应界说多个雷同范例的触发器。虽然每个表最多只能有一个触发器与每种触发事件相关联,但是该触发器可以包含多个触发利用(多个 SQL 语句),可以为每个事件范例编写包含多个具体逻辑的复杂触发器。这样可以在一个触发器中处理多个逻辑,满足复杂的业务需求。
留意:
在计划和实行触发器时,应该审慎思量其数量和复杂性,以制止对数据库性能产生不必要的影响。过多或复杂的触发器可能会导致增加了额外的处理时间和资源斲丧,低落数据库的团体性能。
触发器可以使用 Transact-SQL 编写,并在表创建或修改时使用 CREATE TRIGGER 语句举行界说。即触发器可以在数据库中使用CREATE TRIGGER语句界说,并通过ALTER TRIGGER语句举行修改。触发器可以在表级别或视图级别创建,具体取决于必要对其举行利用的对象。触发器的界说包罗触发器的名称、关联表名、事件范例(INSERT、UPDATE或DELETE)、触发时间(BEFORE或AFTER)以及触发器中要实行的代码。
留意:
触发器可能会对数据库的性能产生影响,特殊是当它们涉及到大量数据的时候。因此,在计划和使用触发器时,应该细致思量其对性能的潜伏影响,并确保它们被正确地设置和处理。
二、触发器优缺点
触发用具有以下优点和缺点:
2.1优点:
- 数据完整性:触发器可以用于欺压实行数据完整性和业务规则,确保数据的有效性和同等性。
- 主动化处理:触发器可以大概在特定的数据库利用发生时主动触发,无需手动干预,提高了开发服从和数据处理的正确性。
- 日志记载和审计:通过在触发器中记载数据变更的信息,可以实现数据的日志记载和审计功能,有助于跟踪数据的变革历史和办理争议。
- 灵活性:触发器可以根据业务需求举行定制和扩展,可以在数据变更时实行自界说的业务规则和逻辑。
- 数据复制和同步:通过触发器,可以在数据发生变更时主动触发复制或同步利用,确保数据的同等性和可用性。
- 安全控制:触发器可以用于实行安全控制计谋,限制对敏感数据的访问和修改。通过在触发器中添加逻辑,可以根据用户权限和角色举行访问控制。
2.2缺点:
- 性能影响:触发器的实行会增加数据库服务器的负载,可能导致性能下降。特殊是复杂的触发器逻辑或在大量数据利用时,对性能的影响更为显着。
- 难以调试:触发器的错误和非常处理可能比力困难,因为它们是在数据库利用时主动触发的,难以举行直接的调试。
- 隐蔽逻辑:触发器的逻辑是隐式的,可能会使代码维护和明白变得更加困难,特殊是当有多个触发器存在时。
- 数据同等性的挑战:触发器的复杂逻辑或错误的计划可能导致数据同等性的问题,必要细致计划和测试。
- 存储空间占用:每个触发器都占用存储空间,并且在每个相关事件发生时都会被加载和运行。假如存在多个触发器,将占用更多的存储空间。
- 可能引发死锁和循环:触发器的实行可能导致死锁情况,尤其是在多个触发器相互依靠或嵌套调用的情况下。别的,触发器的不正确使用可能导致循环触发,进一步影响数据库性能和稳定性。
因此,在使用触发器时,必要细致权衡其优点和缺点,并根据具体需求和性能要求公道计划和使用触发器。
三、触发器种类
SQL Server包罗3种常规范例的触发器:DML触发器、DDL触发器和登录触发器。
当数据库中发生数据利用语言(DML)事件时将调用DML触发器。DML事件包罗在指定表或视图中修改数据的INSERT语句、UPDATE语句或DELETE语句。DML触发器可以查询其他表,还可以包含复杂的Transact-SQL语句。
用户可以计划以下范例的DML触发器。
- ☑ AFTER触发器:在实行了INSERT、UPDATE或DELETE语句利用之后实行AFTER触发器。
- ☑ INSTEAD OF触发器:实行INSTEAD OF触发器代替通常的触发动作。还可为带有一个或多个基表的视图界说INSTEAD OF触发器,而这些触发器可以大概扩展视图可支持的更新范例。
- ☑ CLR触发器:CLR触发器可以是AFTER触发器或INSTEAD OF触发器。CLR触发器还可以是DDL触发器。CLR触发器将实行在托管代码(在.NET Framework中创建并在SQL Server中上载的程序集的成员)中编写的方法,而不用实行Transact--SQL存储过程。
DDL触发器是一种特殊的触发器,它在响应数据界说语言(DDL)语句时触发,可以用于在数据库中实行管理任务,例如,审核以及规范数据库利用。
登录触发器将为响应LOGON事件而引发存储过程。与SQL Server实例建立用户会话时将引发此事件。登录触发器将在登录的身份验证阶段完成之后且用户会话现实建立之前引发。可以使用登录触
发器来审核和控制服务器会话,如通过跟踪登录运动、限制SQL Server的登录名或限制特定登录名的会话数。
四、触发器创建
创建DML触发器、DDL触发器和登录触发器可以通过实行CREATE TRIGGER语句实现。
4.1创建DML触发器
假如用户要通过数据利用语言(DML)事件编辑数据,则实行DML触发器。DML事件是针对表
或视图的NSERT、UPDATE或DELETE语句。
创建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_trigger_option>::=
- [ENCRYPTION]
- [EXECUTE AS Clause]
- <method specifier>::=
- assembly_name.class_name.method name
复制代码 对其举行表明:
- [schema_name.]trigger_name:指定触发器的名称,可以选择性地包含架构名称。trigger name必须遵照标识符规则,但trigger_name不能以“#”或“##”开头.
- ON {table|view}:指定触发器关联的表或视图。视图只能被INSTEAD OF触发器引用。不能对局部或全局暂时表界说DML触发器。
- [WITH <dml_trigger_option>[,...n ]]:可选项,用于指定额外的触发器选项。例如,可以使用ENCRYPTION选项以加密触发器的界说,或使用EXECUTE AS Clause选项以指定触发器实行的安全上下文。
- {FOR | AFTER | INSTEAD OF}:指定触发器实行的时间点。FOR表现在利用之前实行,AFTER表现在利用之后实行,INSTEAD OF表现替代原始利用实行。【AFTER指定DML触发器仅在触发SQL语句中指定的全部利用都已成功实行时才被触发;INSTEAD OF是指定实行DML触发器而不是触发SQL语句,因此,其优先级高于触发语句的利用。】
- {[INSERT][,][UPDATE][,][DELETE]}:指定触发器要响应的事件范例。可以选择INSERT、UPDATE和DELETE关键字来指定触发器响应的利用范例。它们指定数据修改语句,这些语句可在DML触发器对此表或视图举行尝试时激活该触发器。但必须至少指定一个选项。
- [WITH APPEND]:可选项,用于在已有的触发器代码后附加新的代码。指定应该再添加一个现有范例的触发器。
- [NOT FOR REPLICATION]:可选项,指定触发器不会用于数据库复制过程中的利用。即指示当复制代理修改涉及触发器的表时,不应实行触发器。
- AS {sql_statement [;][,...n ]| EXTERNAL NAME <method specifier [;]>}:触发器的代码块位于AS关键字之后。可以编写T-SQL语句和语法来实现所需的功能,也可以使用EXTERNAL NAME来引用托管代码的方法。
- EXECUTE AS:指定用于实行该触发器的安全上下文。
- <method specifier>:对于CLR触发器,指定程序集与触发器绑定的方法。该方法不能带有任何参数,并且必须返回空值。
通常需求都是很普通的,下令按照如下格式即可:
- CREATE TRIGGER [schema_name.]trigger_name
- ON table_name
- [AFTER/INSTEAD OF] {INSERT, UPDATE, DELETE}
- AS
- BEGIN
- -- 触发器逻辑代码
- END
复制代码 以下是DML触发器的示例:
- 例一:提前创建测试表:Employees和相关表-日志表:SalaryLog,然后创建触发器并验证,具体下令如下:
- use SJCX ; --选用数据库
- --创建测试表Employees
- CREATE TABLE Employees (
- ID INT PRIMARY KEY,
- Name VARCHAR(50),
- Salary DECIMAL(10, 2)
- );
-
- --插入数据
- INSERT INTO Employees (ID, Name, Salary)
- VALUES
- (1, 'John Doe', 5000),
- (2, 'Jane Smith', 6000),
- (3, 'Mike Johnson', 4500);
-
- --创建相关表-日志表:SalaryLog
- CREATE TABLE SalaryLog (
- EmployeeID INT,
- OldSalary DECIMAL(10, 2),
- NewSalary DECIMAL(10, 2),
- ChangeDate DATETIME
- );
- --检查表数据
- select * from Employees;
- select * from SalaryLog;
- --创建触发器:
- CREATE TRIGGER UpdateSalaryTrigger
- ON Employees
- FOR UPDATE
- AS
- BEGIN
- -- 如果薪水列被修改,则记录一条日志
- IF UPDATE(Salary)
- BEGIN
- INSERT INTO SalaryLog (EmployeeID, OldSalary, NewSalary, ChangeDate)
- SELECT d.ID, d.Salary, i.Salary, GETDATE()
- FROM inserted AS i
- INNER JOIN deleted AS d ON i.ID = d.ID;
- END
- END;
- --触发器验证:
- --更新"Employees"表中员工ID为1的记录的薪水:
- UPDATE Employees
- SET Salary = 5500
- WHERE ID = 1;
- --结果查验:
- --使用SELECT语句来检查"SalaryLog"表中的日志记录是否生成:
- select * from SalaryLog;
复制代码 在触发器中,我使用了内置的UPDATE()函数来检查是否修改了"Salary"列。假如是,则将相应的旧薪水、新薪水和修改日期插入到名为"SalaryLog"的日志表中。然后我 更新"Employees"表中的1号员工的薪水,并检查"SalaryLog"表中是否出现了对应的日志记载。日志记载运行结果如下:
- 例二:提前创建"Customers"表和"CustomerLog"表 ,然后创建触发器并验证,具体下令如下:
- --示例2:
- --创建"Customers"表
- CREATE TABLE dbo.Customers (
- CustomerId INT PRIMARY KEY,
- CustomerName VARCHAR(100),
- Address VARCHAR(200)
- );
- --创建"CustomerLog"表:
- CREATE TABLE dbo.CustomerLog (
- LogId INT IDENTITY(1,1) PRIMARY KEY,
- CustomerId INT,
- Action VARCHAR(10),
- LogDate DATETIME
- );
- --数据检查:
- SELECT * FROM Customers;
- SELECT * FROM CustomerLog;
- -- 创建触发器
- CREATE TRIGGER dbo.LogInserts
- ON dbo.Customers
- AFTER INSERT
- AS
- BEGIN
- INSERT INTO dbo.CustomerLog (CustomerId, Action, LogDate)
- SELECT CustomerId, 'INSERT', GETDATE()
- FROM inserted;
- END
- --触发器验证:
- --插入数据:
- INSERT INTO dbo.Customers (CustomerId, CustomerName, Address)
- VALUES (1, 'John Doe', '123 Main St'),
- (2, 'Jane Smith', '456 Oak Ave');
- --结果检查:
- --数据检查:
- SELECT * FROM Customers;
- SELECT * FROM CustomerLog;
复制代码 该触发器表明:
- 触发器名字为"dbo.LogInserts",位于"default"架构下。
- 触发器将在"Customers"表中的INSERT利用之后实行。
- 在触发器代码块中,我向"CustomerLog"表中插入新行,包罗插入的"CustomerId"、利用范例为'INSERT'以及当前的日期和时间。
为了测试这个触发器,我是按照以下步调举行:
- 提前要确保数据库中存在"Customers"表和"CustomerLog"表,并且它们具有正确的结构。
- 实行上述CREATE TRIGGER语句以创建触发器。
- 向"Customers"表中插入一些新行。
- 检查"CustomerLog"表是否包含与插入利用相对应的日志行。
日志记载运行结果如下:
- 例三:DELETE范例的DML触发器, 具体下令如下:
- --示例3:
- --借用上面的测试表Customers:
- --创建相关表DeletedCustomersLog:
- CREATE TABLE DeletedCustomersLog (
- ID INT,
- Name VARCHAR(50),
- Address VARCHAR(100),
- DeleteDate DATETIME
- );
- --表检查:
- SELECT * FROM Customers;
- SELECT * FROM DeletedCustomersLog;
- -- 创建触发器
- CREATE TRIGGER DeleteCustomerTrigger
- ON Customers
- AFTER DELETE
- AS
- BEGIN
- -- 记录被删除的客户信息到日志表
- INSERT INTO DeletedCustomersLog (ID, Name, Address, DeleteDate)
- SELECT CustomerID, CustomerName, Address, GETDATE()
- FROM deleted;
- END;
- --触发器验证:
- --尝试从"Customers"表中删除某个客户,并检查触发器是否被触发并在"DeletedCustomersLog"表中生成了相应的日志记录:
- DELETE FROM Customers
- WHERE CustomerID = 2;
- --结果检查:
- SELECT * FROM Customers;
- SELECT * FROM DeletedCustomersLog;
复制代码 日志记载运行结果如下:
4.2创建DDL触发器
在SQL Server 2008中,DDL触发器(Data Definition Language triggers)是用于响应数据库的结构更改利用(如创建、修改或删除表、视图、存储过程等)的触发器。DDL触发器在实行某个DDL语句之前或之后触发,并且可以被用于验证、记载或制止这些结构更改。
DDL触发器可以根据差别的事件和条件举行触发。以下是一些DDL触发器的实行条件:
- 1. AFTER 触发点: DDL触发器可以在相应DDL语句实行之后触发。
- 2. INSTEAD OF 触发点: DDL触发器可以替代相应DDL语句的实行。
- 3. CREATE、ALTER或DROP 事件: DDL触发器可以绑定到特定的CREATE、ALTER或DROP事件上。
- 4. 特定对象范例: DDL触发器可以只针对特定范例的对象(如表、视图、存储过程等)举行触发。
- 5. 条件表达式: DDL触发器可以使用条件表达式来判定是否触发,例如基于某个特定的DDL语句文本或其他相关的条件。
创建DDL触发器的语法格式如下:
- CREATE TRIGGER trigger_name
- ON {ALL SERVER | DATABASE}
- [WITH <ddl_trigger_option>[,...n ]]
- {FOR | AFTER}{event_type | event_group }[,...n]
- AS {sql_statement [;][,...n]| EXTERNAL NAME < method specifier> [;]}
- <ddl_trigger_option>::=
- [ENCRYPTION]
- [EXECUTE AS Clause]
- <method specifier>::=
- assembly_name.class_name.method name
复制代码 对其举行表明:
- - `CREATE TRIGGER trigger_name`: 使用`CREATE TRIGGER`语句创建一个触发器,为触发器指定一个独一无二的名称来替换`trigger_name`。
- - `ON {ALL SERVER | DATABASE}`: 指定触发器绑定到全部服务器级别事件(ALL SERVER)或当前数据库级别事件(DATABASE)。
- - `[WITH <ddl_trigger_option> [,...n ]]`: 可选项,用于指定触发器的属性和选项。常见的选项有`ENCRYPTION`用于加密触发器代码,以及`EXECUTE AS Clause`用于指定在触发器实行时使用的安全上下文。
- - `{FOR | AFTER}{event_type | event_group }[,...n]`: 指定触发器应该响应的事件范例或事件组。可以选择使用`FOR`或`AFTER`关键字,后跟一个或多个事件范例或事件组。例如,可以指定`FOR CREATE_TABLE`表现在创建新表之前触发触发器。
- - `AS {sql_statement [;][,...n]| EXTERNAL NAME <method specifier> [;]}`: 触发器的主体部分。可以是一组SQL语句,以`;`分隔,用于在触发事件发生时实行特定利用。另外也可以使用`EXTERNAL NAME`关键字指定触发器连接到托管代码的方法。
以下是DDL触发器的示例:
创建一个触发器,当对库中表举行创建、修改或删除的利用时,向日志表插入记载,具体下令如下:
- --创建 TestTable 的测试表:
- -- 创建测试表
- CREATE TABLE TestTable (
- ID INT PRIMARY KEY,
- Name VARCHAR(50)
- );
- --创建LogTable 的日志表:
- --用于记录触发器操作
- -- 创建日志表
- CREATE TABLE LogTable (
- EventDateTime DATETIME,
- EventType NVARCHAR(100),
- ObjectName NVARCHAR(100)
- );
- --表检查
- SELECT * FROM TestTable;
- SELECT * FROM LogTable;
-
- --创建触发器:
- CREATE TRIGGER MyDDLTrigger
- ON DATABASE
- FOR CREATE_TABLE, ALTER_TABLE, DROP_TABLE
- AS
- BEGIN
- -- 在这里编写触发器的逻辑
- -- 示例:在触发器被触发时,向日志表插入一条记录
- INSERT INTO dbo.LogTable (EventDateTime, EventType, ObjectName)
- VALUES (
- GETDATE(),
- EVENTDATA().value('(/EVENT_INSTANCE/EventType)[1]','nvarchar(100)'),
- EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]', 'nvarchar(100)')
- )
- END;
- --备注:该触发器的示例逻辑会在任何创建、修改或删除表的操作发生时向一个名为 dbo.LogTable 的日志表插入一条记录
- --测试触发器
- --尝试执行一些包括创建、修改或删除表的操作
- -- 创建新表
- CREATE TABLE NewTable (
- ID INT PRIMARY KEY,
- Name VARCHAR(50)
- );
- -- 修改测试表
- ALTER TABLE TestTable ADD Age INT;
- -- 删除表
- DROP TABLE NewTable;
- --数据检查
- --完成这些操作后,查询日志表 LogTable 来查看触发器的执行情况:
- SELECT * FROM LogTable;
复制代码 通过上述触发器,当任何创建、修改或删除表的利用发生时,将会向 dbo.LogTable 日志表中插入一条记载,记载了触发事件的日期时间、事件范例和对象名称。日志记载运行结果如下:
4.3创建登录触发器
登录触发器在遇到LOGON事件时触发。LOGON事件是在建立用户会话时引发的。触发器可以由
Transact--SQL语句直接创建,也可以由程序集方法创建,这些方法是在Microsoft.NET Framework公共语言运行时(CLR)中创建并上载到SQL Server实例的。SQL Server答应为任何特定语句创建多个触发器。
创建登录触发器的语法格式如下:
- CREATE TRIGGER trigger_name
- ON ALL SERVER
- [WITH <logon_trigger_option>[,..n]]
- {FOR | AFTER} LOGON
- AS {sql_statement [;][,...n ]|EXTERNAL NAME <method specifier>[;]}
- <logon_trigger_option>::=
- [ENCRYPTION]
- [EXECUTE AS Clause]
- <method_specifier>::=
- assembly_name.class_name.method_name
复制代码 该语法是用于创建一个在全部服务器上的触发器,以下是表明:
- trigger_name: 是为触发器指定的名称,可以根据需求举行定名。
- ON ALL SERVER:表现触发器将应用于全部连接到服务器的用户。
- [WITH <logon_trigger_option>[,..n]]:<logon_trigger_option> 是可选参数,用于界说触发器的选项。此中包罗 ENCRYPTION 和 EXECUTE AS Clause。
- {FOR | AFTER} LOGON:FOR 或 AFTER 关键字用于指定触发器是在用户登录之前还是之后实行。
- AS {sql_statement [;][,...n ]|EXTERNAL NAME <method_specifier>[;]}:在这里,可以指定触发器的主体部分。它可以是一个或多个 SQL 语句,以及可选的外部方法规范符。
- <method_specifier>::= assembly_name.class_name.method_name:假如选择使用外部方法,method_specifier 将指定程序集名称、类名称和方法名称。外部方法答应您调用托管代码来实行触发器逻辑。
示例1:创建一个登录触发器,该触发器拒绝TM登录名的成员登录SQL Server。具体下令如下:
- USE master;--将当前会话的默认数据库设置为 master
- GO
- --创建一个名为 TM 的登录账号,并设置密码为 'TMsoft'。
- --MUST_CHANGE 参数表示用户首次登录时必须更改密码,CHECK_EXPIRATION 参数表示密码过期策略启用
- CREATE LOGIN TM WITH PASSWORD ='TMsoft'MUST_CHANGE,
- CHECK_EXPIRATION=ON;
- GO
- --授予登录账号 TM 对服务器状态信息 (sys.dm_exec_sessions) 的查看权限
- GRANT VIEW SERVER STATE TO TM;
- GO
- --创建一个名为 connection_limit_trigger 的登录触发器,并将其绑定到服务器级别的 LOGON 事件上。
- --触发器使用 EXECUTE AS 'TM' 语句指定以登录账号 TM 的身份执行触发器的逻辑。
- CREATE TRIGGER connection_limit_trigger
- ON ALL SERVER
- WITH EXECUTE AS 'TM'
- FOR LOGON
- AS
- BEGIN
- IF ORIGINAL_LOGIN()='TM'AND
- (SELECT COUNT(*)FROM sys.dm_exec_sessions
- WHERE is_user_process=1 AND
- original_login_name='TM')>1
- --判断正在登录的用户是否为 TM,然后通过查询 sys.dm_exec_sessions 视图统计当前活跃的会话数量。
- --如果会话数大于1,则执行回滚操作,阻止用户的登录。
- ROLLBACK;
- END;
复制代码 登录触发器与DML触发器、DDL触发器所存储的位置差别,其存储位置为对象资源管理器中“服
务器对象”/“触发器”。登录触发器connection_limit_trigger中的TM为登录到SQL Server中的登录名。触发器及TM所在的位置如图所示。
创建完该触发器后,当以TM的登录名登录SQL Server时,就会表现如下图所示的提示信息。
示例2:创建登录触发器,禁止名为RestrictedUser的特定用户登录,具体下令如下:
- --创建登录触发器:禁止名为RestrictedUser的特定用户登录
- CREATE TRIGGER LoginTrigger
- ON ALL SERVER -- 触发器将在服务器级别上执行,而不是特定的数据库
- FOR LOGON --触发器将在用户登录到服务器时触发
- AS
- BEGIN
- -- 在此处编写触发器逻辑
- -- 示例:禁止特定用户登录
- IF ORIGINAL_LOGIN() = 'RestrictedUser'
- BEGIN
- ROLLBACK;
- RAISERROR ('Access Denied', 16, 1);
- RETURN;
- END
- END
复制代码 剖析逻辑:
假如触发器检测到原始登录名 (ORIGINAL_LOGIN()) 等于 'RestrictedUser',它会实行以下利用:
- --ROLLBACK: 回滚当前的登录尝试,制止用户登录。
- --RAISERROR: 抛出一个错误消息 'Access Denied',提示访问被拒绝。
- --RETURN: 结束触发器的实行。
- --RAISERROR ('Access Denied', 16, 1) 是用于抛堕落误消息的语句。
- --'Access Denied' 是指要抛出的错误消息的文本内容,表现拒绝访问。
- --16 是指错误的严重级别。在 SQL Server 中,错误级别从 1 到 25 不等,此中级别越高表现错误的严重水平越高。级别 16 表现一般的用户界说错误。
- --1 是指状态值,表现此错误的自界说状态值。
留意:
RAISERROR 已在 SQL Server 2012 及更高版本中被替代为 THROW 语句。因此,在较新的版本中,可以使用 THROW 语句来实现雷同的结果。
五、触发器管理
触发器的查看、修改、重定名与删除等利用都可以使用SQL Server Management Studio管理工具实现。下面会通过SQL Server Management Studio管理工具来查看、修改、重定名、禁用和启用与删除触发器。
5.1查看触发器
查看触发器与查看存储过程雷同。同样可以使用sp_helptext存储过程与sys.sql_modules视图查看触发器。
5.1.1.使用sp_helptext存储过程查看触发器
sp_helptext存储过程可以查看架构范围内的触发器,非架构范围内的触发器是不能用此存储过程查看的,如DDL触发器、登录触发器。
语法格式如下:
- USE YourDatabaseName;
- EXEC sp_helptext 'YourTriggerName';
复制代码 将 YourDatabaseName 替换为要查询触发器所在的数据库名,YourTriggerName 替换为要查看的触发器名称。 单击 "实行" 按钮或按下 F5 键来运行查询。查询结果窗口将表现与指定触发器关联的 T-SQL 代码。
例如sp_helptext存储过程查看上述例子中的DML触发器--【UpdateSalaryTrigger】。SQL语句及运行结果如图所示:
留意:
sp_helptext 存储过程返回与对象关联的全部文本,包罗触发器的完整界说和逻辑代码。假如触发器非常复杂或代码较长,结果可能会被截断或超出表现范围。在这种情况下,您可以使用 SSMS 的结果网格选项卡或将结果导出到文件以查看完整的代码。
5.1.2.获取数据库中触发器的信息
每个范例为TR或TA的触发器对象对应一行,TA代表程序集(CLR)触发器,TR代表SQL触发器。DML触发器名称在架构范围内,因此,可在sys.objects中表现。DDL触发器名称的作用域取决于父实体,只能在对象目录视图中表现。
例如在db2008数据库中,查找范例为TR的触发器。SQL语句及运行结果如图所示。
sys.objects 视图包含了数据库中全部范例的对象(如表、视图、函数、存储过程等),通过 WHERE TYPE='TR' 过滤条件可以只返回触发器范例的对象。虽然触发器也是数据库中的对象,但由于其特殊性质,SQL Server 将其单独列为一个视图来管理触发器相关的元数据信息。因此,使用 sys.triggers 视图可以大概更正确地检索与触发器相关的信息。
假如希望查询数据库中全部触发器的具体信息,建议使用以下查询:
- SELECT *
- FROM sys.triggers;
复制代码 结果如下:
这里将返回指定数据库中全部触发器的具体信息,包罗触发器名称、关联对象、事件范例等。
sys.triggers 视图:专门用于检索与触发器相关的信息。它包含数据库中全部触发器对象的元数据信息,例如触发器名称、所属表名、事件范例等。
在 SQL Server 2008 中,DDL(数据界说语言)触发器无法直接查看其界说和逻辑代码。这是因为 SQL Server 2008 不提供一种简朴的方法来检索 DDL 触发器的完整界说。然而,可以通过查询体系表来获取有关数据库中的 DDL 触发器的一些基本信息。 打开 SQL Server Management Studio (SSMS) 工具并连接到数据库实例,在 "新建查询" 窗口中,输入以下下令:
- USE YourDatabaseName;
- SELECT *
- FROM sys.triggers
- WHERE [type] = 'TR' AND parent_class_desc = 'DATABASE';
复制代码 将 YourDatabaseName 替换为要查询触发器所在的数据库名。
例如想查找我上面所创建的DDL触发器, SQL运行结果如图所示:
留意:
此查询将返回与数据库关联的全部 DDL 触发器的基本信息,但不会包含触发器的完整界说和逻辑代码。假如必要查看特定 DDL 触发器的具体界说和逻辑,请尝试使用其他工具、脚本或第三方插件,如 Red Gate SQL Prompt 或 ApexSQL Refactor,这些工具可以帮助我们更方便地查看和管理 DDL 触发器。
DDL(数据界说语言)触发器和 DML(数据利用语言)触发器是两种差别范例的触发器:
- DDL 触发器(Data Definition Language Triggers):这些触发器对于数据库中的结构性更改事件(例如创建、修改或删除表、视图、存储过程等)举行响应。
- DML 触发器(Data Manipulation Language Triggers):这些触发器对于针对表的数据利用事件(例如插入、更新或删除行)举行响应。
通过 SELECT * FROM sys.objects WHERE TYPE='TR' 查询,将得到包含全部范例的触发器的结果,无论是 DDL 触发器还是 DML 触发器。但是假如想进一步区分 DDL 触发器和 DML 触发器,可以参考以下查询示例:
- SELECT *
- FROM sys.triggers
- WHERE parent_class = 0; -- DDL 触发器
- SELECT *
- FROM sys.triggers
- WHERE parent_class > 0; -- DML 触发器
复制代码 运行结果如图所示:
从结果图可观察到上述已经创建的一些触发器。发现上述查询可以根据 parent_class 列的值来区分 DDL 触发器和 DML 触发器。
除了上述的方法查看触发器以外,也可以通过下面的一些方法举行查看:
在 SQL Server 2008 中,查看数据库中的 DML(数据利用语言)触发器:
- 1. 打开 SQL Server Management Studio (SSMS) 工具并连接到您的数据库实例。
- 2. 在 "对象资源管理器" 中,睁开数据库文件夹,然后睁开 "表" 文件夹。
-
- 3. 找到包含 DML 触发器的表,并睁开该表。
- 4. 在睁开的表节点下,找到 "触发器" 文件夹。在该文件夹中,您将看到与该表关联的触发器列表。
- 5. 右键单击所需的触发器,然后选择 "脚本触发器为" > "创建到" > "新查询编辑器窗口" 或 "剪贴板"。
- - "创建到新查询编辑器窗口":将生成触发器的 T-SQL 脚本,并在新的查询编辑器窗口中打开以举行查看和编辑。
- - "剪贴板":将生成触发器的 T-SQL 脚本,并复制到剪贴板中供您粘贴到其他位置。
通过上述步调,可以查看数据库中表的 DML 触发器及其相关的 T-SQL 脚本。这样就可以了解触发器的逻辑和利用,以满足我们的需求。
留意:
这些步调假设我们已经拥有足够的权限来查看触发器对象。假如遇到任何问题,要确保使用具有适当权限的登录账号连接到 SQL Server 实例。
5.2修改触发器
修改触发器可以通过ALTER TRIGGER语句实现,下面分别对修改DML触发器、DDL触发器、
登录触发器举行介绍。
5.2.1修改DML触发器
修改DML触发器的语法格式如下:
- ALTER TRIGGER trigger_name
- ON table_name
- AFTER/INSTEAD OF {INSERT, UPDATE, DELETE}
- AS
- BEGIN
- -- 触发器逻辑代码
- END;
复制代码 留意几点:
- ALTER TRIGGER 用于修改现有的触发器。
- trigger_name 是要修改的触发器的名称。
- table_name 是触发器所属的表的名称。
- AFTER 或 INSTEAD OF 用于指定触发器在何时触发。AFTER 表现在实行完相应的 DML 利用后触发,而 INSTEAD OF 则表现在代替相应的 DML 利用之前触发。
- {INSERT, UPDATE, DELETE} 是触发器要响应的利用范例。可以选择 INSERT(插入)、UPDATE(更新)或 DELETE(删除),也可以同时选择多个利用范例。
- AS BEGIN ... END 是触发器的主体部分,此中包含触发器的逻辑代码。
例如使用ALTER TRIGGER语句修改DML触发器DeleteCustomerTrigger,当向该表中插入、修改或删除数据时给出提示信息。SQL语句如下:
- --修改DML触发器:DeleteCustomerTrigger
- ALTER TRIGGER DeleteCustomerTrigger
- ON Customers
- AFTER INSERT, UPDATE, DELETE
- AS
- RAISERROR('正在向表中插入、修改或删除数据',16,10);
复制代码 验证修改的触发器,向表中插入数据,结果如下所示:
表结果检查,如图所示:
5.2.2修改DDL触发器
修改DML触发器的语法格式如下:
- ALTER TRIGGER trigger_name
- ON DATABASE
- FOR {EVENT_TYPE}
- AS
- BEGIN
- -- 触发器逻辑代码
- END;
复制代码
- ALTER TRIGGER 用于修改现有的触发器。
- trigger_name 是要修改的 DDL 触发器的名称。
- FOR {EVENT_TYPE} 用于指定触发器要响应的事件范例,可以是 CREATE_TABLE、ALTER_TABLE 或 DROP_TABLE 等。
- BEGIN ... END 是触发器的主体部分,此中包含触发器的逻辑代码。
例如使用ALTER TRIGGER语句修改DDL触发器MyDDLTrigger,防止用户修改数据。SQL语句如下:
- CREATE TRIGGER MyDDLTrigger
- ON DATABASE
- FOR ALTER_TABLE
- AS
- BEGIN
- RAISERROR('只有“MyDDLTrigger”触发器无效时,才可以修改表。', 16, 10);
- ROLLBACK;
- END;
复制代码 验证已修改完成的触发器,对表举行alter table 利用,结果如图所示:
5.2.3修改登录触发器
修改登录触发器的语法格式如下:
- ALTER TRIGGER trigger_name
- ON ALL SERVER
- FOR LOGON
- AS
- BEGIN
- -- 触发器逻辑代码
- END;
复制代码 留意几点:
- ALTER TRIGGER 用于修改现有的触发器。
- trigger_name 是要修改的登录触发器的名称。
- ON ALL SERVER 表现该触发器将应用于全部服务器级别的事件。
- FOR LOGON 指定触发器要响应的事件范例为用户登录事件。
- BEGIN ... END 是触发器的主体部分,此中包含触发器的逻辑代码。
在编写登录触发器时,通常会使用一些体系函数(如 ORIGINAL_LOGIN() 和 HOST_NAME() 等)来获取相关信息,以便举行相应的处理。
例如使用ALTER TRIGGER语句修改登录触发器connection_limit_trigger,将用户名修改为nxt,假如在此登录名下已运行3个用户会话,拒绝nxt登录到SQL Server。SQL语句如下:
- --修改登录触发器:
- ALTER TRIGGER connection_limit_trigger
- ON ALL SERVER
- WITH EXECUTE AS'NXT'
- FOR LOGON
- AS
- BEGIN
- -- 触发器逻辑代码
- IF ORIGINAL_LOGIN ()='NXT' AND
- (SELECT COUNT(*) FROM SYS.dm_exec_sessions
- WHERE is_user_process =1 AND
- original_login_name ='NXT')>3
- ROLLBACK;
- END;
复制代码 验证修改的登录触发器,使用用户名 "NXT" 举行登录尝试,并确保同时存在凌驾3个与该用户名相关的运动会话。
起首修改TM用户名为NXT,定名如下:
- --修改用户名:
- ALTER LOGIN TM
- WITH NAME = NXT;
复制代码 用户名为 "NXT" 并且与该用户名相关的运动会话数凌驾3个,则触发器将触发 ROLLBACK 语句,取消登录尝试,并提供一个错误消息。如图所示:
5.3重定名触发器
重定名触发器可以使用sp_rename体系存储过程实现。使用sp_rename体系存储过程重定名触发器
与重定名存储过程雷同。但是使用该体系存储过程重定名触发器,不会更改sys.sql modules类别视图的definition(用于界说此模块的SQL文本)列中相应对象名的名称,所以建议用户不要使用该体系存储过程重定名触发器,而是删除该触发器,然后使用新名称重新创建该触发器。
可以使用以下语法格式来重定名触发器:
- sp_rename 'old_trigger_name', 'new_trigger_name', 'OBJECT';
复制代码 old_trigger_name 是要重定名的现有触发器的名称,new_trigger_name 是要修改为的新触发器名称。
留意几点:
- sp_rename 是一个体系存储过程,用于重定名数据库对象。
- 'OBJECT' 参数表现要重定名的对象是一个触发器。
- 重定名触发器的利用必要具有适当的权限。
例如:使用sp_rename将触发器DeleteCustomerTrigger重定名为DeleteCusTrigger。SQL语句如下:
- --重命名触发器:
- sp_rename 'DeleteCustomerTrigger','DeleteCusTrigger'
复制代码 检查修改后的触发器,如图所示:
5.4禁用与启用触发器
当不再必要某个触发器时,可将其禁用或删除。禁用触发器不会删除该触发器,该触发器仍旧作为对象存在于当前数据库中。但是,当实行任意NSERT、UPDATE或DELETE语句(在其上对触发器举行了编程)时,触发器将不会引发。已禁用的触发器可以被重新启用,启用触发器会以最初创建它时的方式将其引发。默认情况下,创建触发器后会启用触发器。
5.4.1禁用触发器
使用以下语法格式来禁用触发器:
- DISABLE TRIGGER {trigger_name | ALL}
- ON {table_name | view_name}
复制代码
- trigger_name:要禁用的单个触发器名称。
- ALL:禁用指定表或视图上的全部触发器。
- table_name:要禁用触发器的表名。
- view_name:要禁用触发器的视图名。
留意几点:
- 禁用触发器必要具有适当的权限。
- 当禁用触发器后,相关的 DML 利用将不会触发该触发器的实行。
- 被禁用的触发器仍旧存在于数据库中,并可以在以后重新启用。
例1:使用DISABLE TRIGGER语句禁用DML触发器DeleteCusTrigger,SQL语句如下:
- --禁用DML触发器:
- DISABLE TRIGGER DeleteCusTrigger
- ON CUSTOMERS;
复制代码 例2:使用DISABLE TRIGGER语句禁用DDL触发器MyDDLTrigger,SQL语句如下:
- --禁用DDL触发器:
- DISABLE TRIGGER MyDDLTrigger
- ON DATABASE;
复制代码 例3:使用DISABLE TRIGGER语句禁用登录触发器connection_limit_trigger,SQL语句如下:
- --禁用登录触发器:
- DISABLE TRIGGER connection_limit_trigger
- ON ALL SERVER;
复制代码 检查已经禁用的各个触发器的状态,SQL语句如下:
- --查看触发器状态:0-启动;1-禁用
- SELECT
- name AS trigger_name,
- is_disabled
- FROM
- sys.triggers
- WHERE
- is_disabled = 1;
- --查看登录触发器的状态
- SELECT
- name AS trigger_name,
- is_disabled
- FROM
- sys.server_triggers
- WHERE
- is_disabled = 1;
复制代码 实行结果如图所示:
5.4.2启用触发器
启用触发器并不是重新创建它。已禁用的DDL、DML或登录触发器可以通过实行ENABLE TRIGGER语句重新启用。语法格式如下:
- ENABLE TRIGGER {trigger_name | ALL}
- ON {table_name | view_name}
复制代码
- trigger_name:要启用的单个触发器名称。
- ALL:启用指定表或视图上的全部触发器。
- table_name:要启用触发器的表名。
- view_name:要启用触发器的视图名。
留意几点:
- 启用触发器必要具有适当的权限。
- 当启用触发器后,相关的 DML 利用将会触发该触发器的实行。
- 假如触发器已经是启用状态,则启用触发器利用将不会产生任何影响。
例1:使用ENABLE TRIGGER语句启用DML触发器DeleteCusTrigger,SQL语句如下:
- --启用DML触发器:
- ENABLE TRIGGER DeleteCusTrigger
- ON CUSTOMERS;
复制代码 例2:使用ENABLE TRIGGER语句启用DDL触发器MyDDLTrigger,SQL语句如下:
- --启用DDL触发器:
- ENABLE TRIGGER MyDDLTrigger
- ON DATABASE;
复制代码 例3:使用ENABLE TRIGGER语句启用登录触发器connection_limit_trigger,SQL语句如下:
- --启用登录触发器:
- ENABLE TRIGGER connection_limit_trigger
- ON ALL SERVER;
复制代码 检查已经禁用的各个触发器的状态,结果如下所示:
5.5删除触发器
删除触发器是将触发器对象从当前数据库中永世地删除。通过实行DROP TRIGGER语句可以将
DML、DDL或登录触发器删除,也可以通过利用SQL Server Management Studio手动删除DML、DDL或登录触发器。
5.5.1.DROP TRIGGER语句删除触发器
DROP TRIGGER语句可以从当前数据库中删除一个或多个DML、DDL或登录触发器。
(1)删除DML触发器
删除DML触发器的语法格式如下:
- DROP TRIGGER [IF EXISTS] {trigger_name | table_name.trigger_name}
复制代码
- IF EXISTS(可选):用于在触发器不存在时制止报错。
- trigger_name:要删除的单个触发器名称。
- table_name.trigger_name:要删除的表上的指定触发器名称。
留意几点:
- 删除触发器必要具有适当的权限。
- 当删除触发器后,与该触发器相关的 DML 利用将不再触发该触发器。
- 删除触发器时要小心,确保没有意外删除了必要的触发器。
例如使用DROP TRIGGER语句禁用DML触发器DeleteCusTrigger,SQL语句如下:
- --删除DML触发器
- DROP TRIGGER DeleteCusTrigger
复制代码 (2)删除DDL触发器
删除DDL触发器的语法格式如下:
- DROP TRIGGER [IF EXISTS] {trigger_name | ddl_trigger_name}
- ON {database_name | ALL SERVER}
复制代码
- IF EXISTS(可选):用于在触发器不存在时制止报错。
- trigger_name:要删除的单个触发器名称。
- ddl_trigger_name:要删除的 DDL 触发器的名称。
- database_name:指定触发器所在的数据库名称。
- ALL SERVER:删除全部服务器级别的触发器。
留意以下几点:
- 删除触发器必要具有适当的权限。
- 当删除触发器后,与该触发器相关的 DDL 利用将不再触发该触发器。
- 删除触发器时要小心,确保没有意外删除了必要的触发器。
例如使用DROP TRIGGER语句禁用DML触发器MyDDLTrigger,SQL语句如下:
- ----删除DDL触发器
- DROP TRIGGER MyDDLTrigger
- ON DATABASE;
复制代码 (3)删除登录触发器
删除登录触发器的语法格式如下:
- DROP TRIGGER [IF EXISTS] {trigger_name | logon_trigger_name}
- ON ALL SERVER
复制代码
- IF EXISTS(可选):用于在触发器不存在时制止报错。
- trigger_name:要删除的单个触发器名称。
- logon_trigger_name:要删除的登录触发器的名称。
留意几点:
- 删除触发器必要具有适当的权限。
- 当删除触发器后,与该触发器相关的登录事件将不再触发该触发器。
- 删除触发器时要小心,确保没有意外删除了必要的触发器。
例如使用DROP TRIGGER语句禁用DML触发器connection_limit_trigger,SQL语句如下:
- --删除登录触发器
- DROP TRIGGER connection_limit_trigger
- ON ALL SERVER;
复制代码 提示:
一旦触发器被删除,相关的元数据信息将不再存在于体系视图中。因此,无法通过查询体系视图来确定触发器是否已经被删除。假如必要确认触发器是否已被删除,可以尝试实行与该触发器相关的利用(如插入、更新或删除数据),并观察是否会产生预期的触发器行为。假如触发器不存在,相关的触发器逻辑将不会被触发。
一定要留意,在删除触发器之前,最好备份数据库,以便在必要时举行恢复。
5.5.2.SQL Server Management Studio手动删除触发器
手动删除触发器的步调如下:
(1)打开SQL Server Management Studio,并连接到SQL Server2008中的数据库。
(2)睁开“对象资源管理器”中触发器所在位置。如要删除创建在db2008数据库的触发器,则睁开如图所示的树形结构。
(3)右击要删除的触发器,在弹出的快捷菜单中选择“删除”下令,打开“删除对象”对话框,
如图所示。
(4)在“删除对象”对话框中确认所删除的触发器,单击“确定”按钮即可将该触发器删除。
六、触发器应用场景
结合前面内容的形貌,现总结下触发器的应用场景,以下是一些常见的应用场景:
- 1. 数据完整性束缚:触发器可以用于实行数据完整性束缚,确保特定的业务规则得到满足。例如,在插入或更新利用之前,可以使用触发器验证数据的有效性,并拒绝不符合要求的更改。
- 2. 日志记载:触发器可以用于记载数据库中的数据变革。通过在触发器中编写代码,可以将所做的更改记载到一个日志表中,以便后续分析和审计。这对于跟踪数据修改、审计数据库利用等方面非常有效。
- 3. 数据转换和派生:触发器可以用于根据已有数据生成新的派生数据。例如,当插入一条贩卖记载时,触发器可以根据该记载的某些属性计算并添补相关的陈诉字段;在数据插入或更新利用之前,可以使用触发器对数据举行格式化、计算或转换,以满足特定的需求。
- 4. 数据复制:触发器可以用于在多个数据库之间复制数据。当在源数据库中插入、更新或删除记载时,触发器可以主动同步这些更改到目的数据库中的相应表。这对于将数据从一个表或数据库复制到另一个表或数据库非常有效,确保数据的同等性和可用性。
- 5. 安全控制:触发器可以用于实行安全控制计谋。例如,在敏感数据表上创建触发器,以防止未经授权的访问或修改数据。
- 6. 异步处理:触发器可以用于在后台异步处理相关任务。例如,在处理用户请求时,触发器可以启动一个后台作业,以制止对用户的响应时间产生延长。
- 7.业务规则和逻辑:触发器答应在数据变更时实行自界说的业务规则和逻辑。例如,可以根据特定条件主动更新其他表中的数据、生成自界说报表或触发其他业务流程。
- 8.引用完整性:触发器可以用于实行引用完整性,确保表之间的关联关系得到维护。通过触发器,可以在更新或删除关联表中的数据时欺压实行相关的利用或防止破坏关联关系。
本篇关于触发器的总结就到此结束了,内容如有错误的地方还请兄弟们辅导,假如想了解更多触发器相关的知识可以去看下我的另一篇文章,关于Oracle的触发器总结:http://t.csdnimg.cn/lDeaz
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |