Я пытаюсь внедрить общесистемную регистрацию, в которой будут регистрироваться все неудачные выполнения хранимых процедур в нашем dabatase, и я рассматриваю Extended Events.SQL Server logged failed queries
Я сделал некоторые исследования, и, кажется, довольно легко захватить не удалось заявления, используя следующий код:
--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()
работы, заставляя его захватить весь оператор или ХЕ для вставки записей прямо в некоторую таблицу, если это возможно.
Все вопросы - дайте мне знать.
Можете ли вы подробнее остановиться на 'он верхний метод должен работать как запланированная job.' – TheGameiswar
@TheGameiswar Sure. Я имел в виду, что расширенные события могут выполняться в фоновом режиме и хранить данные с запрошенными запросами в указанном файле. Затем, основываясь на расписании (скажем, ежечасно), я мог бы прочитать этот файл и вставить записи в таблицу Logs.Errors. Теперь это имеет смысл? –
Вам не нужно запускать расширенные события. Запускать и останавливать события как задание, как только вы его запускаете, он работает в фоновом режиме. – TheGameiswar