How to trace T-SQL function calls

后端 未结 9 1314
被撕碎了的回忆
被撕碎了的回忆 2020-12-15 04:43

I\'m trying to debug a rather complicated formula evaluator written in T-SQL UDFs (don\'t ask) that recursively (but indirectly through an intermediate func

相关标签:
9条回答
  • 2020-12-15 05:26

    Use SQL Profiler, I recommend you go overboard on adding events the first time around which will let you get a feel for what you need. Without testing I would add the events for SP:StmtStarted (or Completed or both), SQL:StmtStarted (again Completed or Both).

    0 讨论(0)
  • 2020-12-15 05:29

    Well in the past I have had to take typical values that would be in the UDF and then run just the udf part in a separate query window as straight SQL not a udf using the typical values as variables set with a declare and a set statement. If it is run from a table instead of having only one value, I would set up a temp table or table variable with the input values and then run them through the sql in the UDF (but again as straight SQL not a UDF) through a cursor. By running straight SQL you could have print statements in it to see what is happening. I know this is a pain, but it works. (I go through a simliar process when creating/debugging triggers, setup #inserted and #deleted with my test values and then test the code I intend to put into the trigger, then global replace the # with nothing and add the create trigger code.)

    0 讨论(0)
  • 2020-12-15 05:32

    Maybe you can use SQL CLR to do the tracing as described here How to log in T-SQL

    0 讨论(0)
  • 2020-12-15 05:32

    I use SQL SPY which does what you are looking for and more.

    SQL SPY

    SQL SPY Feature Documentation

    SQL SPY's Incoming SQL Sniffer shows the incoming SQL code of each connection (Includes DDL and DML statement tracking)

    This feature is designed for MS SQL Server 2005\2008, but will work with MS SQL Server 2000 in limited scope. It has the ability to record and report on Incoming SQL. How to use the features: See

    Disclosure: I am part of the SQL SPY team.

    0 讨论(0)
  • 2020-12-15 05:39

    I second the SQL Profiler suggestion. Take some time to set it up so that only the events you are interested in are logged to cut output size. You can output the trace to a file - I have frequently then loaded that file back into a table to enable analysis. (extremely handy for performance analysis, though no doubt someone will tell me that 2008 has this all built in somwehere...)

    Sometimes you won't have permissions to run SQL Profiler as it does slow the server down - ask your DBA to grant you permission on your Dev server. They shouldn't have any problems with that.

    0 讨论(0)
  • 2020-12-15 05:41

    In the SQL profiler, you need: SP:Starting, SP:StmtStarting, SP:Completed, SQL:BatchStarting. Then, you get every entry, exit from the functions/stored procedures.

    alter FUNCTION [dbo].[ufn_mjf](@i numeric(10))
        RETURNS numeric(20) 
    AS
    BEGIN
    declare @datapoint varchar(10)
    
        set @datapoint = 'hello world'
    
        return @i
    END
    go
    drop table foo
    go
    create table dbo.foo ( foo_id numeric(10)) 
    go
    delete from foo
    insert into foo ( foo_id ) values ( 1 )
    insert into foo ( foo_id ) values ( 2 )
    
    select foo_id, dbo.ufn_mjf(foo_id) from foo
    

    with this, I get:

    SQL:BatchStarting   alter FUNCTION [dbo].[ufn_mjf](@i numeric(10))
    SQL:BatchStarting   drop table foo
    SQL:BatchStarting   create table dbo.foo ( foo_id numeric(10)) 
    SQL:BatchStarting   delete from foo
        insert into foo ( foo_id ) values ( 1 )
        insert into foo ( foo_id ) values ( 2 )
        select foo_id, dbo.ufn_mjf(foo_id) from foo
    SP:Starting select foo_id, dbo.ufn_mjf(foo_id) from foo
    SP:StmtStarting set @datapoint = 'hello world'
    SP:StmtStarting return @i
    SP:Completed    select foo_id, dbo.ufn_mjf(foo_id) from foo
    SP:Starting select foo_id, dbo.ufn_mjf(foo_id) from foo
    SP:StmtStarting set @datapoint = 'hello world'
    SP:StmtStarting return @i
    SP:Completed    select foo_id, dbo.ufn_mjf(foo_id) from foo
    

    is that enough for you?

    0 讨论(0)
提交回复
热议问题