programming4us
programming4us
DATABASE

SQL Server 2008 : Advanced Stored Procedure Programming and Optimization - Using Dynamic SQL in Stored Procedures

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
SQL Server allows the use of the EXEC statement in stored procedures to execute dynamic SQL statements. This capability allows you to do things such as pass in object names as parameters and dynamically execute a query against the table name passed in, as in the following example:
IF EXISTS ( SELECT * FROM sys.procedures
WHERE schema_id = schema_id('dbo')
AND name = N'get_order_data')
DROP PROCEDURE dbo.get_order_data
GO
create proc get_order_data
(@table varchar(30), @column varchar(30), @value int)
as
declare @query varchar(255)

select @query = 'select * from ' + @table
+ ' where ' + @column
+ ' = ' + convert(varchar(10), @value)

EXEC (@query)

return

This feature can be useful when you have to pass a variable list of values into a stored procedure. The string contains a comma-separated list of numeric values or character strings, just as they would appear inside the parentheses of an IN clause. If you are passing character strings, you need to be sure to put single quotation marks around the values, as shown in Listing 1.

Listing 1. Passing a Variable List of Values into a Stored Procedure
IF EXISTS ( SELECT * FROM sys.procedures
WHERE schema_id = schema_id('dbo')
AND name = N'find_books_by_type')
DROP PROCEDURE dbo.find_books_by_type
GO
create proc find_books_by_type @typelist varchar(8000)
as

exec ('select title_id, title = substring(title, 1, 40), type, price
from titles where type in ('
+ @typelist + ') order by type, title_id')
go

set quoted_identifier off
exec find_books_by_type "'business', 'mod_cook', 'trad_cook'"
go

title_id title type price
-------- ---------------------------------------- ------------ ------------------
BU1032 The Busy Executive's Database Guide business 14.9532
BU1111 Cooking with Computers: Surreptitious Ba business 14.595
BU2075 You Can Combat Computer Stress! business 15.894
BU7832 Straight Talk About Computers business 14.9532
MC2222 Silicon Valley Gastronomic Treats mod_cook 14.9532
MC3021 The Gourmet Microwave mod_cook 15.894
TC3218 Onions, Leeks, and Garlic: Cooking Secre trad_cook 0.0017
TC4203 Fifty Years in Buckingham Palace Kitchen trad_cook 14.595
TC7777 Sushi, Anyone? trad_cook 14.3279



When using dynamic SQL in stored procedures, you need to be aware of a few issues:

  • Any local variables that are declared and assigned values in the constructed string within an EXEC statement are not available to the stored procedure outside the EXEC command. The lifespan of a local variable is limited to the context in which it is declared, and the context of the EXEC command ends when it completes.

  • Any local variables that are declared and assigned values in the stored procedure can be used to build the dynamic query statement, but the local variables cannot be referenced by any statements within the EXEC string. The commands in the EXEC statement run in a different context from the stored procedure, and you cannot reference local variables declared outside the current context.

  • Commands executed in an EXEC string execute within the security context of the user executing the procedure, not the execution context of the stored procedure. By default, if a user has permission to execute a stored procedure, that user also has implied permission to access all objects referenced in the stored procedure that are owned by the same person who created the stored procedure. However, if a user has permission to execute the procedure but hasn’t explicitly been granted the permissions necessary to perform all the actions specified in the EXEC string, a permission violation occurs at runtime.

  • If you issue a USE command to change the database context in an EXEC statement, it is in effect only during the EXEC string execution. It does not change the database context for the stored procedure (see Listing 2).

Listing 2. Changing Database Context in an EXEC Statement
use bigpubs2008
go
create proc db_context as
print db_name()
exec ('USE AdventureWorks print db_name()')
print db_name()
go

exec db_context
go

bigpubs2008
AdventureWorks
bigpubs2008

Using sp_executesql

If you want to have the flexibility of dynamic SQL but better persistence of parameterized execution plans, you should consider using sp_executesql instead of EXEC in your stored procedures. The syntax for sp_executesql is as follows:

sp_executesql @SQL_commands, @parameter_definitions, param1,...paramN

sp_executesql operates just as the EXEC statement with regard to the scope of names, permissions, and database context. However, sp_executesql is more efficient for executing the same SQL commands repeatedly when the only change is the values of the parameters. Because the SQL statement remains constant and only the parameters change, SQL Server is more likely to reuse the execution plan generated for the first execution and simply substitute the new parameter values. This saves the overhead of having to compile a new execution plan each time.

Listing 3 provides an example of a stored procedure that takes up to three parameters and uses sp_executesql to invoke the dynamic queries.

Listing 3. Invoking Dynamic Queries in a Procedure by Using sp_executesql
IF EXISTS ( SELECT * FROM sys.procedures
WHERE schema_id = schema_id('dbo')
AND name = N'find_books_by_type2')
DROP PROCEDURE dbo.find_books_by_type2
GOgo
create proc find_books_by_type2 @type1 char(12),
@type2 char(12) = null,
@type3 char(12) = null
as

exec sp_executesql N'select title_id, title = substring(title, 1, 40),
type, price from bigpubs2008.dbo.titles where type = @type',
N'@type char(12)',
@type = @type1
if @type2 is not null
exec sp_executesql N'select title_id, title = substring(title, 1, 40),
type, price from bigpubs2008.dbo.titles where type = @type',
N'@type char(12)',
@type = @type2
if @type3 is not null
exec sp_executesql N'select title_id, title = substring(title, 1, 40),
type, price from bigpubs2008.dbo.titles where type = @type',
N'@type char(12)',
@type = @type3
go

set quoted_identifier off
exec find_books_by_type2 'business', 'mod_cook', 'trad_cook'
go

title_id title type price
-------- ---------------------------------------- ------------ ------------------
BU1032 The Busy Executive's Database Guide business 14.9532
BU1111 Cooking with Computers: Surreptitious Ba business 14.595
BU2075 You Can Combat Computer Stress! business 15.894
BU7832 Straight Talk About Computers business 14.9532

title_id title type price
-------- ---------------------------------------- ------------ ------------------
MC2222 Silicon Valley Gastronomic Treats mod_cook 14.9532
MC3021 The Gourmet Microwave mod_cook 15.894

title_id title type price
-------- ---------------------------------------- ------------ ------------------
TC3218 Onions, Leeks, and Garlic: Cooking Secre trad_cook 0.0017
TC4203 Fifty Years in Buckingham Palace Kitchen trad_cook 14.595
TC7777 Sushi, Anyone? trad_cook 14.3279



Note that the SQL command and parameter definition parameters to sp_executesql must be of type nchar, nvarchar, or ntext. Also, to ensure that the query plan is reused, make sure that the object names are fully qualified in the SQL command.

Using Output Parameters with sp_executesql

One important concept to remember about dynamic SQL is that it runs in a separate scope from the stored procedure that invokes it. This is similar to when a stored procedure executes another stored procedure. Because local variables are available only within the current scope, a nested procedure cannot access a local variable declared in the calling procedure. Similarly, you cannot access a local variable declared outside the scope of a dynamic SQL statement. With stored procedures, you can work around this limitation by using input and output parameters to pass values into and out of a nested stored procedure.

If you use sp_executesql to execute dynamic SQL, you can use output parameters to pass values both into and out of the dynamic SQL query through local variables. As described in the previous section, the second parameter to sp_executesql is a comma-separated list that defines the parameters you will be using within the dynamic SQL statement. As with parameter definitions for a stored procedure, parameters passed to sp_executesql can also be defined as output parameters. To get the values back out, you define the parameter as an output parameter in the parameter list and then specify the OUTPUT keyword when passing the variable in the corresponding argument list for sp_executesql.

Listing 4 shows an example of a stored procedure that uses sp_executesql to execute a dynamic SQL query and return a value via an output parameter. You can use the parameters inside the dynamic SQL–like parameters inside a stored procedure. Any values assigned to output parameters within the dynamic SQL query are passed back to the local variable in the calling procedure.

Listing 4. Using Output Parameters in sp_executesql
IF EXISTS ( SELECT * FROM sys.procedures
WHERE schema_id = schema_id('dbo')
AND name = N'get_avg_price')
DROP PROCEDURE dbo.get_avg_price
GO
create proc get_avg_price @dbname sysname,
@type varchar(12) = '%'
as

declare @dsql nvarchar(500),
@avgval float

/*********************************************************
** build the dynamic query using the @avg and @type as
** variables, which will be passed in via sp_executesql
**********************************************************/
select @dsql = 'select @avg = avg(isnull(price, 0)) from '
+ @dbname+ '..titles '
+ 'where type like @type'

/*************************************************************
** submit the dynamic query using sp_executesql, passing type
** as an input parameter, and @avgval as an output parameter
** The value of @avg in the dynamic query will be passed
** back into @avgval
*************************************************************/
exec sp_executesql @dsql, N'@avg float OUT, @type varchar(12)',
@avgval OUT, @type
print 'The avg value of price for the titles table'
+ ' where type is like ''' + @type
+ ''' in the ' + @dbname + ' database'
+ ' is ' + ltrim(str(@avgval, 9,4))

go

exec get_avg_price @dbname = 'bigpubs2008',
@type = 'business'
go

The avg value of price for the titles table where type is like 'business'
in the bigpubs2008 database is 15.0988


exec get_avg_price @dbname = 'bigpubs2008',
@type = DEFAULT
go

The avg value of price for the titles table where type is like '%' in the
bigpubs2008 database is 0.3744


Other  
 
Top 10
Free Mobile And Desktop Apps For Accessing Restricted Websites
MASERATI QUATTROPORTE; DIESEL : Lure of Italian limos
TOYOTA CAMRY 2; 2.5 : Camry now more comely
KIA SORENTO 2.2CRDi : Fuel-sipping slugger
How To Setup, Password Protect & Encrypt Wireless Internet Connection
Emulate And Run iPad Apps On Windows, Mac OS X & Linux With iPadian
Backup & Restore Game Progress From Any Game With SaveGameProgress
Generate A Facebook Timeline Cover Using A Free App
New App for Women ‘Remix’ Offers Fashion Advice & Style Tips
SG50 Ferrari F12berlinetta : Prancing Horse for Lion City's 50th
- Messages forwarded by Outlook rule go nowhere
- Create and Deploy Windows 7 Image
- How do I check to see if my exchange 2003 is an open relay? (not using a open relay tester tool online, but on the console)
- Creating and using an unencrypted cookie in ASP.NET
- Directories
- Poor Performance on Sharepoint 2010 Server
- SBS 2008 ~ The e-mail alias already exists...
- Public to Private IP - DNS Changes
- Send Email from Winform application
- How to create a .mdb file from ms sql server database.......
programming4us programming4us
programming4us
 
 
programming4us