7

I'm attempting to track all executions of a stored procedure (Including from inside other stored procedures) and the statements of that procedure - is this possible with extended events? My current extended event is:

CREATE EVENT SESSION [EVENT_NAME] ON SERVER
ADD EVENT sqlserver.rpc_completed(SET collect_data_stream=(1)
ACTION(sqlserver.database_id,sqlserver.database_name,sqlserver.server_principal_name,sqlserver.session_id)
WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)) AND [sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%MY_STORED_PROCEDURE_NAME%'))),
ADD EVENT sqlserver.sp_statement_completed(
ACTION(sqlserver.database_id,sqlserver.database_name,sqlserver.server_principal_name,sqlserver.session_id)
WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)) AND [sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%MY_STORED_PROCEDURE_NAME%'))),
ADD EVENT sqlserver.sql_batch_completed(
ACTION(sqlserver.database_id,sqlserver.database_name,sqlserver.server_principal_name,sqlserver.session_id)
WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)) AND [sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%MY_STORED_PROCEDURE_NAME%')))
ADD TARGET package0.event_file(SET filename=N'TraceData')
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)
GO

But this doesn't seem to work unless I execute the procedure manually. Any best practice method to do this?

1 Answer 1

11

Your way is very expensive.
You can use module_start event to track this efficiently.

Prepare a demo

CREATE OR ALTER PROCEDURE dbo.TrackedProcedure
    @param int 
AS
BEGIN
    SELECT @param
END 

GO

CREATE OR ALTER PROCEDURE dbo.WrapperProcedure
    @passParam int 
AS
BEGIN
    /* do something */

    SELECT 'WrapperProcedure' AS context

    EXEC dbo.TrackedProcedure 
        @param = @passParam
END
GO

And a draft of the XE session - you should add some data persisting options.

CREATE EVENT SESSION [TrackProcedure] ON SERVER 
ADD EVENT sqlserver.module_start
(
    SET collect_statement=1
    ACTION
    (
        sqlserver.client_app_name,                 /* Additional audit info */
        sqlserver.database_name,                   /* Additional audit info */
        sqlserver.session_server_principal_name,   /* Additional audit info */
        sqlserver.username,                        /* Additional audit info */
        sqlserver.sql_text,
        sqlserver.tsql_stack
    )
    WHERE 
    (
        [object_type]='P ' /* The space behind P is necesssary */
        AND [object_name]=N'TrackedProcedure'
    )
)

Then I execute code like this:

/* Batch 1 */
EXEC dbo.TrackedProcedure 
    @param = 10
GO

/* Batch 2 */
EXEC dbo.WrapperProcedure
    @passParam = 5 -- int
GO

XE showing captured data

You can see that the sql_text column is the input buffer - capturing the outer scope.
statement column has the exact line.

I blog more about parsing the tsql_stack here. Investigating Errors With Extended Events

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.