SQL Server触发器无法审计存储过程调用,因其仅响应DML事件且无法获取上层调用者信息;应使用SQL Server Audit或Extended Events实现可靠审计。

SQL Server触发器本身无法审计存储过程调用——它根本“看不到”调用者是谁,也收不到CALL指令的上下文。 你想在触发器里记录“谁执行了哪个存储过程”,这条路走不通。真正能定位调用来源的,只有外部跟踪或调用方主动透传标识。
为什么触发器里查不到 caller_proc
触发器响应的是 DML 事件(如 INSERT),不是函数调用栈。即使 INSERT 语句写在 sp_update_order 里,触发器内部:
-
@@PROCID返回的是触发器自身的对象 ID,OBJECT_NAME(@@PROCID)拿到的是触发器名,不是上层存储过程名 -
EVENTDATA()在 DML 触发器中不可用;DDL 触发器虽可用,但只含事件类型、T-SQL 文本片段,不含调用它的存储过程名 -
sys.dm_exec_input_buffer不能在触发器内安全调用,且需要额外权限,跨会话也不生效
想审计存储过程执行,该用 SQL Server Audit
这不是触发器的任务,而是 SQL Server Audit 的标准场景。它基于 Extended Events,开销低、权限可控、支持落地文件或 Windows 安全日志:
- 必须先在
master创建服务器审核:CREATE SERVER AUDIT [ProcExecAudit] TO FILE ( ... ) - 再在目标数据库创建审核规范:
CREATE DATABASE AUDIT SPECIFICATION [AuditProcExec] FOR SERVER AUDIT [ProcExecAudit] ADD (EXECUTE ON DATABASE::[YourDB] BY [public]) - 启用后,每次
EXEC dbo.sp_do_something都会记录object_name = 'sp_do_something'、session_id、principal_name等,但不包含参数值 - 若需还原完整命令,得配合
fn_get_audit_file()解析原始事件,或直接捕获rpc_completed事件(更细粒度)
如果必须关联触发器和调用方,只能靠 SESSION_CONTEXT 透传
这是唯一可控、可落地的“伪审计”方式,但依赖业务代码配合:
- 在存储过程中执行 DML 前,显式设置:
EXEC sys.sp_set_session_context @key = N'caller_proc', @value = N'sp_charge_customer'; - 在触发器里读取:
CAST(SESSION_CONTEXT(N'caller_proc') AS SYSNAME),再写入审计表 - 必须确保触发器与存储过程运行在同一会话(不能是链接服务器、作业、异步任务)
- 比老式
CONTEXT_INFO更安全:无需二进制转换、线程隔离、长度无硬限制(32KB)
真要查某次异常触发背后是谁调的,别在触发器里埋点——直接开 Extended Events 会话抓 sql_batch_completed 或 rpc_completed,按 session_id 关联原始批处理文本。那才是真实、不可篡改的调用链路。

















