Create table with instruction into #parameter in stored procedure - sql

I want to create a table from this code in SQL Server, but the stored procedure returns an error
CREATE PROCEDURE Recovery_CountryCode (#NombreTabla SYSNAME)
AS
DECLARE #ParamDefinition nvarchar(500);
DECLARE #SQLString nvarchar (4000);
SET #SQLString=N'SELECT Name
INTO #TableName
FROM AdventureWorks2008R2.Production.Location';
SET #ParamDefinition=N'#TableName SYSNAME';
EXECUTE sp_executesql #SQLString, #ParamDefinition, #TableName=#NombreTabla;
GO
I want avoid define table
When I call the stored procedure:
EXEC Recovery_CountryCode #NombreTabla='Paises';
I get the follow message:
Mens. 102, Nivel 15, Estado 1, LĂ­nea 2
Sintaxis incorrecta cerca de '#TableName'.

You can just concatenate the SQL inside your procedure
CREATE PROCEDURE Recovery_CountryCode (#NombreTabla SYSNAME)
AS
DECLARE #ParamDefinition nvarchar(500);
DECLARE #SQLString nvarchar (4000);
SET #SQLString=N'SELECT Name INTO ' +
#NombreTabla +
' FROM AdventureWorks2008R2.Production.Location';
EXECUTE sp_executesql #SQLString
GO

You can't bind variables to table names in this way. You need to do something like
Declare #sql nvarchar(max), #NombreTable sysname = 'Test'
Set #sql = N'Select Name Into ' + #NombreTable +
N' From AdventureWorks2008R2.Production.Location
exec sp_executesql #sql
http://www.sommarskog.se/dynamic_sql.html is recommended reading.

Related

How to create sp_executesql to drop tables dynamicaly

For some reasons, I am trying to create a dynamic script to drop tables that I created before. I couldnt do the syntax right and I need help for this matter.
When I run my script, it gives the error:
"Procedure expects parameter '#statement' of type 'ntext/nchar/nvarchar'."
and this is my script. It has an error in sp_executesql statement, I guess. How can I fix this?
DECLARE #sql VARCHAR(MAX);
DECLARE #tmpTableName VARCHAR(max);
SET #tmpTableName = '##gmAAA_COLLATION';
SET #sql = 'DROP TABLE #tmpTableName';
EXEC sp_executesql #sql, N'#tmpTableName NVARCHAR(max)', #tmpTableName;
You cannot do this with static SQL, i.e. a table name can never be a parameter in SQL statements like these. This is also true for column names, schema names etc.
If you want to do this using sp_executesql, you can build the SQL dynamically as follows:
SET #sql = 'DROP TABLE '+QUOTENAME(#tmpTableName);
EXEC sp_executesql #sql;
PS: The #stmt parameter of the sp_executesql procedure needs to be of type NVARCHAR(...).
SET #sql = 'DROP TABLE '+#tmpTableName;
EXEC sp_executesql #sql;
The sp_executesql requires nvarchar for the #stmt and #params parameters
so change the data Types of variables form varchar to be nvarchar as following
DECLARE #sql NVARCHAR(MAX);
DECLARE #tmpTableName VARCHAR(max);
Try the following query:-
SET #sql = 'DROP TABLE #tmpTableName'; EXEC (#sql)
OR
DECLARE #sql NVARCHAR(MAX);
DECLARE #tmpTableName NVARCHAR(max)
SET #tmpTableName = '##gmAAA_COLLATION';
SET #sql = 'DROP TABLE'+QUOTENAME(#tmpTableName);
EXEC sp_executesql #sql,N'#tmpTableName NVARCHAR(max)',#tmpTableName

Execute Stored Procedure from Stored Procedure w/ dynamic SQL capturing output

Inside a stored procedure (A) I need to call a stored procedure (X) inside a specific database and capture the output. X returns a single value.
From what I understand I need to provide the DB name of X to the stored procedure in A and I need to use dynamic SQL to build the query on execution targeting the desired database.
What am unable to figure out is how to capture output from X in A to work with the result.
You could use sp_executesql to dynamically call your nested Stored Procedure.
DECLARE #db AS SYSNAME
DECLARE #return_value AS INT
DECLARE #output_value AS INT
DECLARE #sql AS NVARCHAR(MAX)
-- Set your DB name
SET #db = N'mydb'
/*
Use sp_executesql to dynamically pass in the db and stored procedure
to execute while also defining the values and assigning to local variables.
*/
SET #sql = N'EXEC #rtn = ' + #db + '.dbo.[your_stored_procedure] #output OUTPUT'
EXEC sp_executesql #sql
, N'#rtn AS INT, #output AS INT OUTPUT'
, #return_value = #rtn
, #output_value = #output OUTPUT
Adding to the above answer, following is the way to call stored procedures dynamically by passing parameters.
DECLARE #SpName VARCHAR(1000)
SELECT #SpName = DeleteLiveSP FROM dbo.ArchivalInfo (NOLOCK) WHERE TableName = #TableName
DECLARE #SqlString nvarchar(2000)
DECLARE #ParamDef nvarchar(2000)
SET #SqlString = N'exec '+#SpName + ' #CriteriaParam'
SET #ParamDef = N'#CriteriaParam XML'
EXECUTE sp_executesql #SqlString ,#ParamDef, #CriteriaParam = #Criteria

How to pass a table variable using sp_executesql

I'm trying to create a table using sp_executesql but I keep getting an error that says "Incorrect syntax near '#_TableName'. Any idea what I'm doing wrong here?
Here's the code that I'm using:
DECLARE #SQLString NVARCHAR(MAX),
#ParamDefinition NVARCHAR(MAX),
#TableName NVARCHAR(MAX);
SET #TableName = N'[dbo].[MyTable]';
SET #SQLString = N'SELECT * FROM #_TableName;';
SET #ParamDefinition = N'#_TableName NVARCHAR(max)';
EXEC sp_executesql #SQLString, #ParamDefinition,
#_TableName = #TableName;
That yields the error:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '#_TableName'.
If I hard code the table name and the column type (I have to do both) then the query works, otherwise I get the incorrect syntax message for both those variables.
In case you're wondering, I want to put this code inside a stored procedure, so that if anyone wants to create or modify a table then they call this stored procedure which can run additional validations.
Figured out the problem.
Apparently sp_executesql expects the parameter definition for a table to be of a table type (see this answer for an example: https://stackoverflow.com/a/4264553/21539).
An easier way to solve this problem was to insert the variables names directly into the SQLStatement string as follows:
DECLARE #SQLString NVARCHAR(MAX),
#TableName NVARCHAR(MAX);
SET #TableName = N'[dbo].[MyTable]';
SET #SQLString = N'SELECT * FROM ' + #TableName + ';';
SET #ParamDefinition = N'#_TableName NVARCHAR(max);
EXEC sp_executesql #SQLString;

Using OUTPUT Parameters within Dynamic SQL within Stored Procedures- Possible?

I have a SP that I have created to check for validations and return an OUTPUT Parameter of 0 (No Error) or 1 (Error). However, I have to run this SP within Dynamic SQL since it will be ran through a loop of different data.
Can I pull the OUTPUT from the SP through the EXEC sp_executesql #SQL?
I can not post the actual code, but I can give an example..
DECLARE
#SQL nVARCHAR(4000),
#SPName VARCHAR(200),
#Parm1 VARCHAR(100),
#Parm2 VARCHAR(100),
#Parm3 VARCHAR(100),
#ParmDefinition nVARCHAR(400),
#Error nVARCHAR(1)
SELECT
#SPName = 'spExample1',
#Parm1 = '000000',
#Parm2 = '111111',
#Parm3 = '#Err=#Error OUTPUT',
SET #SQL = 'EXEC ' + #SPName + ' ' + #Parm1 + ',' + #Parm2 + ',' + #Parm3 + '
SET #ParmDefinition = N'#Err2 nVARCHAR(1) OUTPUT'
EXEC sp_executesql #SQL, #ParmDefinition, #Err2=#Error OUTPUT
The #SQL Variable ends up being:
EXEC spExample1 000000, 111111, #Err=#Error OUTPUT
^^Which works perfectly by itself.
Basically I'm trying to get the OUTPUT through the above code, but when it's ran through Dynamically.
Is this possible or is there another way to do this?
The way things kind of play out in the end appear to be:
EXEC sp_executesql EXEC spExample1 000000, 111111, #Err=#Error OUTPUT, #Err2 nVARCHAR(1) OUTPUT, #Err2=#Error OUTPUT
After looking at that it looks ridiculous, however any help would definitely be appreciated.
Sorry for the delay :D, the following code works perfectly (For N.. output and input parameters) please try this (source):
CREATE PROCEDURE Myproc
#parm varchar(10),
#parm1OUT varchar(30) OUTPUT,
#parm2OUT varchar(30) OUTPUT
AS
SELECT #parm1OUT='parm 1' + #parm
SELECT #parm2OUT='parm 2' + #parm
GO
DECLARE #SQLString NVARCHAR(500)
DECLARE #ParmDefinition NVARCHAR(500)
DECLARE #parmIN VARCHAR(10)
DECLARE #parmRET1 VARCHAR(30)
DECLARE #parmRET2 VARCHAR(30)
SET #parmIN=' returned'
SET #SQLString=N'EXEC Myproc #parm,
#parm1OUT OUTPUT, #parm2OUT OUTPUT'
SET #ParmDefinition=N'#parm varchar(10),
#parm1OUT varchar(30) OUTPUT,
#parm2OUT varchar(30) OUTPUT'
EXECUTE sp_executesql
#SQLString,
#ParmDefinition,
#parm=#parmIN,
#parm1OUT=#parmRET1 OUTPUT,#parm2OUT=#parmRET2 OUTPUT
SELECT #parmRET1 AS "parameter 1", #parmRET2 AS "parameter 2"
go
drop procedure Myproc
I haven't tested this in depth, but I did note the following:
When calling stored procedures, you can't mix-and-match named and not-named parameters. So instead of
EXEC sp_executesql #SQL, #ParmDefinition, #Err2=#Error OUTPUT
use
EXEC sp_executesql #SQL, #ParmDefinition, #Error OUTPUT
but, since the output parameter defined for sp_executesql is #Err2, it needs to be
EXEC sp_executesql #SQL, #ParmDefinition, #Err2 OUTPUT
This should work.

Using variable inside dynamic SQL

I have the below SQL..What I am trying to do is use the Parameter defined at the stored procedure level inside dynamic SQL:
CREATE PROCEDURE [dbo].[Test]
(#DealID NVARCHAR(500),
#OUTPUT NVARCHAR(MAX) OUTPUT,
#FeeType CHAR(1)
) -- I want to use this parameter inside dynamic SQL query
AS
DECLARE #exec_str NVARCHAR(MAX)
DECLARE #ParmDefinition NVARCHAR(MAX)
BEGIN
SET #exec_str = N'DECLARE #ParmDefinition NVARCHAR(500)
SELECT * FROM #FeeType' --This is where I want to use the variable
DECLARE #ParamDefinition nvarchar(max)
SET #ParamDefinition = N'#OUTPUT NVARCHAR(MAX) OUTPUT'
EXEC sp_executesql #exec_str, #ParamDefinition
Can someone please tell me how to do it?
Thanks
In SQL Server Identifiers can't be parameterized.
Since you are using dynamic SQL anyway, you can do something like this:
SET #exec_str= N'Select * from '+ #FeeType
EXEC(#exec_str)
However, this is vulnerable to SQL injection attacks. To reduce the risk to minimum you should check first that such a table name exists, and I would also use quotename just to be on the safe side:
IF EXISTS
(
SELECT 1
FROM Information_Schema.Tables
WHERE TABLE_NAME = #FeeType
)
BEGIN
SET #exec_str= N'Select * from '+ QUOTENAME(#FeeType)
EXEC(#exec_str)
END