Capturing and Debugging a SQL Stored Procedure call from BizTalk
So you design your strongly typed stored procedure to take table types from BizTalk and it’s running great with your test cases. It works well through the unit testing, but then you start running larger jobs and suddenly SQL is choking on it.
Ever wish you could just run that SQL call directly in SSMS with those exact several thousand rows for the table type parameters, and step through it using the debugger? Well, you can using SQL Server Profiler (and/or Server Traces). I used this technique recently to help a client resolve a particularly thorny issue that came up when they tried to process some larger messages.
To walk through the process of doing this, I’ll use a database named BTSTrainDb with a stored procedure (dbo.usp_DemoTableTypeSP) that takes a user-defined Table Type (dbo.DemoTableType) as a parameter and then just selects * from it (echoing it back to the caller).
First, fire up SQL Server Profiler and create a new trace. Uncheck all of the event boxes. On the Events Selection tab, check off Show all events and Show all columns, and then select the RPC:Completed and the RPC:Starting event; it’s not a bad idea to uncheck the Text column for the RPC:Completed event (as this will repeat the data from the RPC:Starting event).
Next, you’ll want to add filters that will capture only calls to usp_DemoTableTypeSP on BTSTrainDb; here, I’m filtering on the database and object names – you would want a username filter as well if there were other users calling the procedure that you’d like to ignore:
Click OK and then click Run to start the trace.
This will work fine for RPCs using small amounts of data (like test cases with only a few records). That can be helpful if you just need to get a quick template for running the stored procedure directly during testing, but once you start feeding in larger amounts of data you’ll see the message “Trace Skipped Records.” The sample below shows both types of occurrences:
So, I have my small sample (super handy for quickly debugging the procedure when I make changes), but when I tried to send in a large sample the Profiler tried to avoid crashing its GUI by loading several megabytes of text data. To resolve this, you’ll need to start a server side trace. This is easily accomplished by exporting the trace you just made; click “File->Export->Script Trace Definition->For SQL Server 2005-SQL11…”. Load the resulting file up in SSMS. You’ll want to increase the @maxfilesize parameter and change the filename to something SQL Server will be able to write cool; take a note of the TraceID that it creates as well, as you’ll probably want to stop or dispose of it later:
When I run the big file through again now, I get the whole procedure call in the c:\temp\DemoTrace.trc file. I can stop the trace by running the following stored procedure (the first parameter is the TraceID from earlier, the second is the status value):
exec sp_trace_setstatus 2, 0
If I wanted to remove the trace entirely it’d be exec sp_trace_setstatus 2, 2; or to start it up again exec sp_trace_setstatus 2, 1. See http://msdn.microsoft.com/en-us/library/ms176034.aspx for more information. When I open up the DemoTrace.trc file in profiler, I can get the whole call:
(note the ID column here, which indicates how many rows there are – the file generated almost 165000 rows!)
You can export it by going to File->Export->Extract SQL Server Events->Extract Transact-SQL Events… and saving it as a .sql file. I now have full debugging access to the SQL stored procedure with the exact data that’s been causing problems!