【发布时间】:2017-04-12 08:59:21
【问题描述】:
我正在尝试实现系统范围的日志记录,它将在我们的数据库中记录所有失败的存储过程执行,并且我正在查看扩展事件。
我做了一些研究,使用以下代码似乎很容易捕获失败的语句:
--Create an extended event session
CREATE EVENT SESSION what_queries_are_failing ON SERVER
ADD EVENT sqlserver.error_reported (
ACTION (sqlserver.sql_text
, sqlserver.tsql_stack
, sqlserver.database_id
, sqlserver.username
)
WHERE ([severity] > 10)
)
ADD TARGET package0.asynchronous_file_target (
SET filename = 'C:\XEventSessions\what_queries_are_failing.xel'
, metadatafile = 'C:\XEventSessions\what_queries_are_failing.xem'
, max_file_size = 5
, max_rollover_files = 5
)
WITH (MAX_DISPATCH_LATENCY = 5 SECONDS)
GO
-- Start the session
ALTER EVENT SESSION what_queries_are_failing ON SERVER STATE = START
GO
;WITH events_cte
AS (
SELECT DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), CURRENT_TIMESTAMP), xevents.event_data.value('(event/@timestamp)[1]', 'datetime2')) AS [err_timestamp]
, xevents.event_data.value('(event/data[@name="severity"]/value)[1]', 'bigint') AS [err_severity]
, xevents.event_data.value('(event/data[@name="error_number"]/value)[1]', 'bigint') AS [err_number]
, xevents.event_data.value('(event/data[@name="message"]/value)[1]', 'nvarchar(512)') AS [err_message]
, xevents.event_data.value('(event/action[@name="sql_text"]/value)[1]', 'nvarchar(max)') AS [sql_text]
, xevents.event_data
FROM sys.fn_xe_file_target_read_file('S:\XEventSessions\what_queries_are_failing*.xel', 'S:\XEventSessions\what_queries_are_failing*.xem', NULL, NULL)
CROSS APPLY (
SELECT CAST(event_data AS XML) AS event_data
) AS xevents
)
SELECT *
FROM events_cte
ORDER BY err_timestamp;
但是我想立即将失败的语句存储到一个表中,我们称之为Logs.Errors,但我找不到方法,并且上面的方法必须作为预定的工作。
现在,我们的程序如下所示:
CREATE PROCEDURE [dbo].[MyProcedure]
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
SELECT 1;
END TRY
BEGIN CATCH
EXECUTE Logs.PrintError;
EXECUTE Logs.LogError;
END CATCH
END
Logs.LogError 过程使用 DBCC INPUTBUFFER(); 但它不捕获参数,只是捕获执行的确切过程。这就是我能从中得到的一切:
+----------------------------+-----------+-----------+------------------------------+
| ErrorMessage | EventType | Parameter | Statement |
+----------------------------+-----------+-----------+------------------------------+
| Incorrect syntax near '.'. | RPC Event | 0 | DbName.dbo.FailedProcedure;1 |
+----------------------------+-----------+-----------+------------------------------+
如果可能的话,我正在寻找一种方法,通过强制 DBCC INPUTBUFFER() 捕获整个语句或 XE 将记录直接插入某个表来使 DBCC INPUTBUFFER() 工作。
任何问题 - 让我知道。
【问题讨论】:
-
能否详细说明
he upper method would have to work as a scheduled job. -
@TheGameiswar 当然。我记得扩展事件可以在后台运行并将失败的查询信息存储到给定的文件中。然后根据时间表(假设每小时一次),我可以读取该文件并将记录插入
Logs.Errors表。现在更有意义了吗? -
你不需要将扩展事件启动和停止事件作为作业运行,一旦启动,它就会在后台运行
-
你可以使用批量启动,停止事件,看看我在dba.se上的回答stackoverflow.com/questions/36098446/…
标签: sql-server stored-procedures dbcc extended-events