Av rating:
Total votes: 42
Total comments: 10


Pop Rivett
Pop Rivett's SQL Server FAQ
18 September 2006

Setting a Variable from Dynamic SQL

Q: Pop Rivett, how do I set variables from dynamically-executed SQL that I can then access?'

Pop: Bless you, my boy, for asking. Setting a variable within dynamic SQL in Transact SQL is a much more common problem than you might think. From looking at the documentation, you might be led to believe that the only way to pass back results from dynamically-executed SQL is via a result set. But to my way of thinking, where one just wants one or more values in variables, this makes for tedious processing. However, fear not. There is a way of doing it using sp_ExecuteSQL that, for some reason, was never documented in Books Online. Such an omission would never have happened in my day, laddie, I can tell you…

Anyway, I digress. Here is my solution its minimal form. In the list of parameters that you pass to sp_ExecuteSQL, you declare an output variable for values you want passed back to the calling routine, and supply the variable to which to pass it in the parameter value list:

DECLARE @i INT
EXEC
sp_executesql N'select @i = 999', N'@i int output', @i output
SELECT @i

-- You can provide several variables, of course.

DECLARE @i INT, @j INT, @k VARCHAR(20)
EXEC sp_executesql N'select @i = 34, @j = 644, @k = ''hello world''',

  
N'@i int output,@j int output,@k Varchar(20) output', 
  
@i output, @j output, @k output
SELECT @i, @j, @K 

And here is an example of the technique, where one of number of stored procedures which pass back a string output variable is called dynamically. The name of the stored procedure is passed in @SPName and the Dynamic SQL is built up in @SPCall the return value is passed in @rc and any error number is passed into @Error:

DECLARE @OutputParameter VARCHAR(100) ,
       
@error INT ,
       
@SPName VARCHAR(128) ,
       
@SPCall NVARCHAR(128) ,
       
@rc INT
SELECT
@SPCall = 'exec ' + @SPName + ' @OutputParameter output'
EXEC @rc = sp_executesql @SPCall, N'@OutputParameter varchar(100) output',
@OutputParameter output
SELECT @Error = @@error

Q. Gosh Pop, executeSQL seems extraordinarily useful. What other magic does it perform, that isn't in BOL?

Pop: Well, let me see, did you know that one can use it to execute dynamic SQL that relies on the database context, in the context of another database / server? No?

Well, it works like this….

EXEC ('exec svr.dbname.dbo.sp_executesql N''grant select on mytable
to myuser'''
) 

This will allow myuser to access mytable on the remote server.So. Let's imagine you want to write a stored procedure that grants access to a user, @username, on any table, @tablename, in any database, @databasename, based on any server, @servername. You might then use this trick to go about it like this:

DECLARE @sql VARCHAR(1000)
SELECT @sql = 'exec ' + @servername + '.' + @databasename
+ '.dbo.sp_executesql N''grant select on '
+ @tablename + ' to ' + @username + ''''
EXEC (@sql) 

Now run along you young scallywags…and make sure you have execute access to the remote sp_executesql before you try that out!!



This article has been viewed 8740 times.
Pop Rivett

Author profile: Pop Rivett

Pop spent his formative years working in assembler on IBM Series/1 but retrained in VB when that went out of fashion. He soon realised how little relational database expertise existed in most companies and so started to spend most of his time working on that. He now sticks to architecture, release control / IT processes, SQL Server, DTS, SSIS, and access methods in VB/ASP/.NET/Crystal Reports/reporting services. He has been involved with SQL Server since the old days of v4.2 to v2005. He tries to stay away from anything presentation oriented (see www.mindsdoor.net). Theoretically he is semi-retired but seems to keep being offered potentially interesting work.

Search for other articles by Pop Rivett

Rate this article:   Avg rating: from a total of 42 votes.


Poor

OK

Good

Great

Must read
 
Have Your Say
Do you have an opinion on this article? Then add your comment below:
You must be logged in to post to this forum

Click here to log in.


Subject: If only I'd thought of this...
Posted by: Phil Factor (view profile)
Posted on: Monday, September 18, 2006 at 12:33 PM
Message: Since I read this, I have been hurriedly changing lots of SQL code that uses EXECUTE and INSERT just to get a few variables, into Pop Rivett's method. Ah, the shame of it. sp_ExecuteSQL has a lot of tricks up its sleeve. (e.g. preventing SQL Injection)

Subject: I couldn't believe it
Posted by: Anonymous (not signed in)
Posted on: Monday, September 18, 2006 at 12:47 PM
Message: When I saw the code, I couldn't believe it could work. Now I do! Extraordinary.

Well done Mr Rivett Sir.

Subject: Awesome
Posted by: ByrdMan (view profile)
Posted on: Wednesday, September 20, 2006 at 3:21 PM
Message: I, too, have dynamic sql within sprocs thatI kinda bamboozle my way through to get the results I need. Welnow, I shorten that code by 75 lines with this well-taught script. Thanks again.

Subject: DB Object Dependencies Lost?
Posted by: Anonymous (not signed in)
Posted on: Thursday, September 21, 2006 at 9:11 AM
Message: My only caution with that command is that when trying to ascertain db object dependencies, you may miss a few (e.g. you call a view or sp in you sp_execute string). I'm not sure if they have fixed this in later versions of SQL server (2005), but it has been a problem for me in the current version. Still, it has its uses, you just need to not overdo it . . .

Subject: Not grumpy enough
Posted by: Anonymous (not signed in)
Posted on: Monday, September 25, 2006 at 8:59 PM
Message: For an old guy hes not very grumpy, so here is my grumpy input:

Dynamic SQL is difficult to debug and doesn't take advantage of the stored procedure precompiler. Before implementing dynamic SQL I ~always~ try really hard to work out how to do it another way.

Subject: Re: Not Grumpy Enough
Posted by: Phil Factor (view profile)
Posted on: Tuesday, September 26, 2006 at 2:05 PM
Message: Speaking as an old guy, I'm not sure that we are any grumpier than anyone else. Pop Rivett is, by contrast, as benign as Santa, unless provoked by the foolishness of an over-confident novice. On the subject of Dynamic SQL we tend to be smilingly tolerant, because, in earler versions of SQL Server, it was often only by using Dynamic SQL that one could persuade the Query Optimiser to do the decent thing and use the perfectly sensible indexes provided. I'd also like to reiterate my warning about the dangers of SQL Injection when using dynamic SQL, and the complication of having to allow the user access to the tables involved, rather than just he stored procedure, thereby negating some of the value of access via stored-procedure. Bah!

Subject: RE: Re: Not Grumpy Enough
Posted by: nigelrivett (view profile)
Posted on: Wednesday, September 27, 2006 at 7:31 AM
Message: >> Pop Rivett is, by contrast, as benign as Santa
This would be the Santa from Futurama?

>> and doesn't take advantage of the stored procedure precompiler
It can take advantage of cached query plans though - and sp_executesql allows passing of parameters which will allow re-use of more plans.

>> Before implementing dynamic SQL I ~always~ try really hard to work out how to do it another way.
Couldn't agree more without being paid :).
Often dynamic sql is an indication of poor design - or an unwillingness to correct the design.

Subject: You just helped save my tush!
Posted by: Anonymous (not signed in)
Posted on: Wednesday, November 01, 2006 at 1:40 PM
Message: Nice job! Seriously, I was pulling my hair out trying to make this work before I read your article.:)

Subject: ESAT ERKEC
Posted by: Anonymous (not signed in)
Posted on: Wednesday, April 18, 2007 at 3:04 AM
Message: USE sp_executesql that is much better then exec
because if you use exec sql server looks is it stored procedure or another thinks.

Subject: Great.... Thanks.....
Posted by: Anand (view profile)
Posted on: Tuesday, June 03, 2008 at 10:34 AM
Message: I have been thinking and spending close to 2 hours to set value to a variable using dynamic SQL.. This post helped me a lot..

THANKS FOR A GREAT POST.

 









Phil Factor
Bunnikins!
 When an IT manager is selected as a victim of office politics of a large corporate, it is time for him to engage in... Read more...



 View the blog
Using Powershell to Generate Table-Creation Scripts
 For all of us who learn best by trying out examples, Bob Sheldon produces a PowerShell script file for... Read more...

SQL Toolbelt 2008: Predominantly an Engineering Task
 The conversion of the Red-Gate tools to be compatible with SQL Server 2008 might not seem, on first... Read more...

Audit Crosschecks
 In this short article, the second of a 2-part series, William suggests a solution, using SQL Data... Read more...

XML Jumpstart Workbench
 In which Robyn and Phil decide that the best way of starting to learn XML is to jump in and take a ride... Read more...

Discovering Security Uses for SQL Compare
 Much of the security of SQL Server is implemented as part of the database schema. This provides some... Read more...

Beginning SQL Server 2005 Reporting Services Part 1
 Steve Joubert begins an in-depth tour of SQL Server 2005 Reporting Services with a step-by-step guide... Read more...

Ten Common Database Design Mistakes
 Database design and implementation is the cornerstone of any data centric project (read 99.9% of... Read more...

SQL Server Full Text Search Language Features
 SQL Full-text Search (SQL FTS) is an optional component of SQL Server 7 and later, which allows fast... Read more...

Beginning SQL Server 2005 Reporting Services Part 2
 Continuing his in-depth tour of SQL Server 2005 Reporting Services, Steve Joubert demonstrates the most... Read more...

Executing SSIS Packages
 Nigel Rivett demonstrates how to execute all SSIS packages in a given folder using either an SSIS... Read more...

Over 150,000 Microsoft professionals subscribe to the Simple-Talk technical journal. Join today, it's fast, simple, free and secure.

Join Simple Talk