Debugging dynamic sql + dynamic tables in MS SQL Server 2008
I have a messy stored procedure which uses dynamic sql.
I can debug it in runtime by adding print @sql;
where @sql;
is the string containing the dynamic SQL, right before I call execute (@sql);
.
Now, the multi-page stored procedure also creates dynamic tables and uses them in a query. I want to print those tables to the console right before I do an execute
, so that I know exactly what the query is trying to do.
However, the SQL Server 08 does not like that. When I try:
print #temp_table;
and try to compile the S.P. I get this error:
The name "#temp_table" is not permitted in this context. Valid expressions are constants, constant expressions, and (in some contexts) variables. Column names are not pe开发者_Go百科rmitted.
Please help.
EDIT:
I am a noob when it comes to SQL. However, the following statement: select * from #tbl;
does not print anything to the console when it is run non-interactively; the print statement works though.
The following statement has incorrect syntax: print select * from #tbl;
. Is there a way for me to redirect the output of select to a file, if stdout is not an option?
Thanks.
When we use dynamic SQl we start by having a debug input variable in the sp (make it the last one and give it a default value of 0 (to indicate not in debug mode that way it won't break existing code calling the proc).
Now when you run it in debug mode, you print instead of execute or you print and execute but you always rollback at the end. If you need to see the data at various stages, the best thing to do is the second. Then before you rollback you put the data you want to see into a a table varaiable (This is important it can't be a temp table). after the rollback, select from the table variable (which did not go out of scope with the rollback) and run your print tstatments to see the queries which were run.
Debugging this way the only way you'll get output is
select * from #temp_table;
Alternatively, look into the debugging features built into SQL Server Management Studio. For example, this web page may help you
SQL Server Performance . com
You can print Variables, but not tables. You can, however, SELECT from the #table.
Now, if the table is created, filled up and modified in a single statement that is executed, then you can view the state of the table as it was before being modified, but the data will have changed since.
of course, as soon as the dynamic sql finishes, the #table is no longer available so you're stuck!
To counter that, you can insert into a ##Table (note the double hash marks) in your dynamic SQL along with the #table and then query that ##table at the end of execution of the dynamic sql.
for as much as I hate cursors, give this a try:
SET NOCOUNT ON
CREATE TABLE #TempTable1
(ColumnInt int
,ColumnVarchar varchar(50)
,ColumnDatetime datetime
)
INSERT INTO #TempTable1 VALUES (1,'A',GETDATE())
INSERT INTO #TempTable1 VALUES (12345,'abcdefghijklmnop','1/1/2010')
INSERT INTO #TempTable1 VALUES (null,null,null)
INSERT INTO #TempTable1 VALUES (445454,null,getdate())
SET NOCOUNT OFF
DECLARE @F_ColumnInt int
,@F_ColumnVarchar varchar(50)
,@F_ColumnDatetime datetime
DECLARE CursorTempTable1 CURSOR FOR
SELECT
ColumnInt, ColumnVarchar, ColumnDatetime
FROM #TempTable1
ORDER BY ColumnInt
FOR READ ONLY
--populate and allocate resources to the cursor
OPEN CursorTempTable1
PRINT '#TempTable1 contents:'
PRINT ' '+REPLICATE('-',20)
+' '+REPLICATE('-',50)
+' '+REPLICATE('-',23)
--process each row
WHILE 1=1
BEGIN
FETCH NEXT FROM CursorTempTable1
INTO @F_ColumnInt, @F_ColumnVarchar, @F_ColumnDatetime
--finished fetching all rows?
IF @@FETCH_STATUS <> 0
BEGIN --YES, all done fetching
--exith the loop
BREAK
END --IF finished fetching
PRINT ' '+RIGHT( REPLICATE(' ',20) + COALESCE(CONVERT(varchar(20),@F_ColumnInt),'null') ,20)
+' '+LEFT( COALESCE(@F_ColumnVarchar,'null') + REPLICATE(' ',50) ,50)
+' '+LEFT( COALESCE(CONVERT(char(23),@F_ColumnDatetime,121),'null') + REPLICATE(' ',23) ,23)
END --WHILE
--close and free the cursor's resources
CLOSE CursorTempTable1
DEALLOCATE CursorTempTable1
OUTPUT:
#TempTable1 contents:
-------------------- -------------------------------------------------- -----------------------
null null null
1 A 2010-03-18 13:28:24.260
12345 abcdefghijklmnop 2010-01-01 00:00:00.000
445454 null 2010-03-18 13:28:24.260
If I knew that your temp table had a PK, I'd give a cursor free loop example.
精彩评论