登录触发器触发存储过程以响应 LOGON 事件。 使用 SQL Server 实例建立用户会话时,将引发此事件。 登录触发器会在登录的身份验证阶段完成之后触发,但在实际建立用户会话之前。 因此,所有在触发器中生成的消息(例如错误消息和PRINT语句所产生的消息)将会被重定向到SQL Server错误日志。 如果身份验证失败,则登录触发器不会触发。
可以使用登录触发器来审核和控制服务器会话,例如跟踪登录活动、限制 SQL Server 的登录名或限制特定登录名的会话数。 例如,在以下代码中,登录触发器会拒绝由登录名 login_test 发起的登录尝试,如果该登录名已经创建了三个用户会话。
USE master;
GO
CREATE LOGIN login_test WITH PASSWORD = '3KHJ6dhx(0xVYsdf' MUST_CHANGE,
CHECK_EXPIRATION = ON;
GO
GRANT VIEW SERVER STATE TO login_test;
GO
CREATE TRIGGER connection_limit_trigger
ON ALL SERVER WITH EXECUTE AS 'login_test'
FOR LOGON
AS
BEGIN
IF ORIGINAL_LOGIN()= 'login_test' AND
(SELECT COUNT(*) FROM sys.dm_exec_sessions
WHERE is_user_process = 1 AND
original_login_name = 'login_test') > 3
ROLLBACK;
END;
请注意,LOGON 事件对应于可在 事件通知中使用的AUDIT_LOGIN SQL 跟踪事件。 触发器和事件通知之间的主要区别是触发器与事件同步引发,而事件通知是异步的。 这意味着,例如,如果要停止建立会话,则必须使用登录触发器。 无法将AUDIT_LOGIN事件的事件通知用于此目的。
指定第一个和最后一个触发器
可以在 LOGON 事件上定义多个触发器。 您可以使用 sp_settriggerorder 系统存储过程将这些触发器中的任何一个设置为事件触发的第一个或最后一个触发器。 SQL Server 不保证剩余触发器的执行顺序。
管理交易
在 SQL Server 触发登录触发器之前,SQL Server 将创建独立于任何用户事务的隐式事务。 因此,当第一个登录触发器开始触发时,事务计数为 1。 在所有登录触发器执行完成后,事务将被提交。 与其他类型的触发器一样,如果登录触发器完成事务计数为 0 的执行,SQL Server 将返回错误。 ROLLBACK TRANSACTION 语句会把事务的计数重置为 0,即使该语句是在嵌套事务中执行的。 COMMIT TRANSACTION 可能会将事务计数递减到 0。 因此,我们建议不要在登录触发器内发出 COMMIT TRANSACTION 语句。
在登录触发器中使用 ROLLBACK TRANSACTION 语句时,请考虑以下事项:
在 ROLLBACK TRANSACTION 之前进行的任何数据修改都会被回滚。 这些修改包括当前触发器所做的修改,以及以前在同一事件上执行的触发器所做的修改。 不会执行特定事件的任何剩余触发器。
当前触发器继续执行 ROLLBACK 语句之后出现的任何剩余语句。 如果这些语句中的任何一个修改了数据,这些改动将不会被回滚。
如果在 LOGON 事件上执行触发器时出现以下任一条件,则不会建立用户会话:
原始隐式事务被回滚或者失败。
触发器正文中引发了严重性大于 20 的错误。
禁用登录触发器
登录触发器可以有效地防止所有用户(包括固定服务器角色的成员 sysadmin )成功连接到数据库引擎。 当登录触发器阻止连接时,固定服务器角色的成员 sysadmin 可以使用专用管理员连接或以最小配置模式(-f)启动数据库引擎进行连接。 有关详细信息,请参阅 数据库引擎服务启动选项。
相关任务
| 任务 | 主题 |
|---|---|
| 介绍如何创建登录触发器。 可以从任何数据库创建登录触发器,但在服务器级别注册并驻留在 master 数据库中。 | CREATE TRIGGER (Transact-SQL) |
| 介绍如何修改登录触发器。 | ALTER TRIGGER (Transact-SQL) |
| 介绍如何删除登录触发器。 | DROP TRIGGER (Transact-SQL) |
| 介绍如何返回有关登录触发器的信息。 |
sys.server_triggers(Transact-SQL) sys.server_trigger_events(Transact-SQL) |
| 介绍如何捕获登录触发器事件数据。 |