SSMS 2008: Debugging made easy? - sql

I want to alter the procedure sys.sp_executesql in the master database (in the enhanced procedures folder or whatever that's called in English) because I want the procedure to print everything I pass to it.
My code is getting a bit ugly and bloated with all the...
if #d=1 print #sqlstatement (#d für debug)
...statements in front of my dynamic SQL execute statements. I have to do this because SSMS will not tell be the line number of an error of dynamic SQL. I print all the dynamic SQL before execution so that I know exactly what dynamic sql came before the error.
How I get rid of all the print statements to clean my code?

Simply find them all and erase, what else?
Or find the code, which produces this dynamic sql and modify it for non-producing such a code.

Related

What is the proper way to execute Dynamic SQL?

We have lots of SQL scripts in our codebase, which produce dynamic SQL statements, and we execute these statements against the database with
EXEC (#FINALSQL)
It is declared like this
DECLARE #FINALSQL NVARCHAR(MAX);
In one of our scripts, we now get an error when executing the dynamic SQL:
Error Number: 2812
Error Severity: 16
ErrorState: 62
ErrorMessage: Could not find stored procedure
with the SQL statement following.
The error number is related to the the error message but still couldn't find any related issue of how to resolve this problem.
I have also read this question but it didn't help because I already enclosed dynamic SQL in brackets
calling EXEC() generates error: could not find stored procedure
Any ideas what could have caused the problem?
Update: the use of #FINALSQL is to create Updates for an amount on tables based on condition in the script.
The answer to almost anything dynamic can be found in Erland Sommarskog's
tour de force.
http://www.sommarskog.se/dynamic_sql.html
"Execute" is optional for the first statement in a batch when executing a stored procedure. There is likely some formatting error in the string and the parser is trying to interpret the first word as a procedure name after failing to parse it otherwise.
If you have no option to capture the string, then use an Extended Event session or trace to capture the query for errors.
If it was a real procedure, then I 'd suspect that current database is wrong. A "USE mydatabase;" as the first thing in the string would fix that. But you state this is not the case. Also, the procedure name was not listed in the error message.

Run long SQL script for each database

I have a long SQL script i'd like to run for each of my databases on one server. What's the best way to do that?
I found this in my research:
EXEC sp_msforeachdb "
IF '?' IN ('lib1','lib2','lib3')
BEGIN
use ?;
exec 'my_sp_long_sql_script'
END
"
I tried it but it needed me to create the sp in each library, which kind of defeats the purpose of the loop. Or how do I automate creating a sp for each library?
All I want to do is run my long_sql_script for each of my databases.
Use the fully qualified name of the stored procedure instead of its relative name, to retrieve it from whereever it is defined. This is how SQL Server itself works.

How can I get the stored procedure returned columns without knowing the input parameters?

I want to execute a stored procedure virtually and get the returned columns. I use fmtonly like below :
set fmtonly on
exec spName null
set fmtonly off
but using fmtonly caused to run all the lines of code and result of this work is ERROR.
Is there any solution for doing this work?
You need to use sp_describe_first_result_set which is new to SQL Server 2012. Note that this requires you to provide the input parameters (at least the types).
In T-SQL development one is expected to know what procedures is calling and what is the expected result set. Before SQL server 2012 there was very little support for dynamic, runtime, discovery of procedure output and required parameters. This new procedure, along with others like sp_describe_undeclared_parameters can be used to create tools that need to explore the available programming API surface. The very fact that these were added to 2012 should indicate that the equivalent cannot be properly handled pre-2012. Solutions like loopback linked servers have many problems, primarily because they actually execute the code with potential disastrous effects.

Stored procedure SQL SELECT statement issue

I am using SQL Server 2008 Enterprise on Windows Server 2008 Enterprise. In a stored procedure, we can execute a SELECT statement directly. And it could also be executed in this new way, I am wondering which method is better, and why?
New method,
declare #teststatement varchar(500)
set #teststatement = 'SELECT * from sometable'
print #teststatement
exec (#teststatement)
Traditional method,
SELECT * from sometable
regards,
George
FYI: it’s not a new method, it is known as Dynamic SQL.
Dynamic SQL are preferred when we need to set or concatenate certain values into sql statements.
Traditional or normal way sql statements are recommended, because stored procedures are complied. Complied on first run "Stored Procedure are Compiled on First Run"
, execution plan of statements are being created at the time of compilation.
Dynamic sqls are ignored while creating execution plans, because it is taken as string (VARCHAR or NVARCHAR as declared).
Refer following articles for more details about dynamic query and stored procs
Introduction to Dynamic SQL Part 1
Introduction to Dynamic SQL Part 2
Everything you wanted to know about Stored Procedures
The traditional method is safer, because the query is parsed when you save it. The query in the 'exec' method is not parsed and can contain errors.
The "new" way, as mentioned, has nothing to do with SQL 2008. EXEC has been available for quite some time. It's also - in most cases - a Very Bad Idea.
You lose parameterization - meaning you are now vulnerable to SQL Injection. It's ugly and error-prone. It's less efficient. And it creates a new execution scope - meaning it can't share variables, temp tables, etc. - from it's calling stored proc.
sp_executesql is another (and preferred) method of executing dynamic SQL. It's what your client apps use, and it supports parameters - which fixes the most glaring problem of EXEC. However, it too has very limited use cases within a stored proc. About the only redeeming use is when you need a dynamic table or column name. T-SQL does not support a variable for that - so you need to use sp_executesql. The number of times you need or should be doing that are very low.
Bottom line - you'd be best off forgetting you ever heard of it.

SQL Studio - "Modify Stored Procedure" Script Errors

In MS SQL Server Management Studio 2005:
If you have the setting Tools|Options|Scripting|"Include IF NOT EXISTS clause" set to true, modifying a stored procedure will create a strange script that doesn't even work. It looks something like the following: (ellipsis used for brevity)
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS [...]
BEGIN
EXEC dbo.sp_executesql #statement = N'
ALTER procedure [dbo].[p_Procedure]
[...]
'
END
This obviously doesn't work because the only way the ALTER statement is called, is if the stored procedure DOESN'T exist.
The question is thus: is there any way of changing this generated code? A template out there somewhere (this doesn't seem to be related to the build in Templating tools)?
(A slight explanation for this behavior: scripting a CREATE statement generates the same code in which the IF NOT EXISTS makes more sense)
There are some issues on this topic on MS-feedback site.
Here are one:
https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=260519
Here are one comment on that issue (from the bottom of the page linked above):
In SQL2000, the approach was If
exists, DROP followed by a CREATE.
This worekd flawlessly and covered all
cases. It wored so well that we built
our deployment off of this scripting
model. Since SQl2005 entered our
world, we have had manual, cumbersome
workarounds to replace the automated
scripting that was lost in the move to
SQL2000.
Please do readd the If exists, DROP
followed by a CREATE approac. It was
great the way