I am trying to make a dynamic stored procedure.
Here is the initial code
Declare #sqlstrsel as nvarchar(max) ;
Declare #cols as nvarchar(max) ;
Declare #tables as nvarchar(max) ;
Declare #condt as nvarchar(max) ;
Set #cols='*'
Set #tables='products'
Set #condt=''
Set #sqlstrsel = 'select ' + #cols+ 'from ' +#table +#condt
Exec (#sqlstrsel)
This code works fine, but when changed to a stored procedure like below
Alter proc selectT
#cols nvarchar(max) ;
#tables nvarchar(max) ;
#condt nvarchar(max) ;
As
Begin
Declare #sqlstrsel as nvarchar(max) ;
Set #sqlstrsel = 'select ' + #cols+ 'from ' +#table +#condt
Exec (#sqlstrsel);
End
When I execute this proc in a new query, by providing the parameters,
Set #par1='*'
Set #par2= 'products'
Set #par3 =''
Exec selectT(#par1,#par2,#par3)
I get two errors
Procedure or function 'selectt' expect parameter '#cols which was not provided,
And
Incorrect syntax near' #par1'
Par1 to the par 3 are declared beforehand.
Related
I want to execute the following T-SQL dynamic statement:
CREATE PROCEDURE MergeTable #TableName NVARCHAR(max)
AS BEGIN
DECLARE #MergeStatement NVARCHAR(max)
SET #MergeStatement = 'SELECT Query FROM dbo.QueryMergeDWH WHERE SourceTableName = ' + #TableName
EXEC sp_executesql #MergeStatement
END
EXEC MergeTable #TableName = 'SGPREINVOICE'
However, this gives me the following error:
Msg 207, Level 16, State 1, Line 17 Invalid column name
'SGPREINVOICE'.
This actually works:
SELECT 'SELECT Query FROM dbo.QueryMergeDWH WHERE SourceTableName = ' + 'SGPREINVOICE'
What am I doing wrong here?
You need to parameterize you dynamic query. So you pass #TableName all the way through
CREATE PROCEDURE MergeTable #TableName NVARCHAR(max)
AS
DECLARE #MergeStatement NVARCHAR(max);
SET #MergeStatement = '
SELECT Query
FROM dbo.QueryMergeDWH
WHERE SourceTableName = #TableName;
';
EXEC sp_executesql
#MergeStatement,
N'#TableName nvarchar(max)',
#TableName = #TableName;
GO
But it's unclear what's dynamic about that, you could just as well do
CREATE PROCEDURE MergeTable #TableName NVARCHAR(max)
AS
SELECT Query
FROM dbo.QueryMergeDWH
WHERE SourceTableName = #TableName;
GO
I want to search GTIN option in admin product list. So, for that I am providing GTIN value in ProductLoadAllPaged store procedure. Now, when I search GTIN value from product list at that time throw datatable error and from console application get message that System.Data.SqlClient.SqlException (0x80131904): Must declare the scalar variable "#GTIN"..
Here is store procedure added code,
ALTER PROCEDURE [dbo].[ProductLoadAllPaged]
(
#GTIN nvarchar(50) = null--AWAZ
)
AS
BEGIN
...........
--SKU (exact match)
IF #SearchSku = 1
BEGIN
SET #sql = #sql + 'OR p.[Sku] = #OriginalKeywords '
END
--NEW ADDED CODE FOR GTIN SEARCH
IF #GTIN is not null
BEGIN
SET #sql = #sql + 'AND p.Gtin = #GTIN'
END
--localized product name
SET #sql = #sql + '
UNION
SELECT lp.EntityId
FROM LocalizedProperty lp with (NOLOCK)
WHERE
lp.LocaleKeyGroup = N''Product''
AND lp.LanguageId = ' + ISNULL(CAST(#LanguageId AS nvarchar(max)), '0') + '
AND ( (lp.LocaleKey = N''Name'''
..........
END
In the stored procedure change this line of code:
EXEC sp_executesql #sql, N'#Keywords nvarchar(4000), #OriginalKeywords nvarchar(4000)', #Keywords, #OriginalKeywords
To this:
EXEC sp_executesql #sql, N'#Keywords nvarchar(4000), #OriginalKeywords nvarchar(4000), #GTIN nvarchar(50)', #Keywords, #OriginalKeywords, #GTIN
This will add your new parameter when executing the dynamic SQL query.
I am writing a query which need to append the database name dynamically.
The query gets values from a table (in another database) , and I would interested to know if there is a better approach/way.
So my query looks like following :
DECLARE #TagNames AS VARCHAR(MAX) --Probably this is not a Global variable
DECLARE #QUERY AS VARCHAR(MAX)
SET #QUERY ='SELECT #TagNames = coalesce( #TagNames + '','','''') +
fldTagName FROM '+ dbo.fnGetZiConfigValue('KEYNAME')+'.dbo.tblTags Where
fldInterpolate = 1 AND fldUnitID = 13'
EXEC (#QUERY)
When I execute this , I get an error,
Must declare the scalar variable "#TagNames".
It is for sure not a global variable. You have to "declare" it inside dynamic SQL and return outside just like you'd do this with stored procedure.
DECLARE #TagNames AS VARCHAR(MAX) --Probably this is not a Global variable
DECLARE #QUERY AS NVARCHAR(MAX)
SET #QUERY = N'SELECT #TagNames = coalesce( #TagNames + '','','''') +
fldTagName FROM '+ QUOTENAME(dbo.fnGetZiConfigValue('KEYNAME'))+'.dbo.tblTags Where
fldInterpolate = 1 AND fldUnitID = 13'
exec sp_executesql #QUERY, N'#TagNames VARCHAR(MAX) OUTPUT', #TagNames OUTPUT
for sp_executesql dynamic sql and it's params declaration must be NVarchar.
I am using SQL Server 2012, I am going to Create Store Procedure which copies a column from a table in a variable, Could any one please tell me what is Wrong with this code?
alter Procedure Id_Fetch
#Col varchar(50)=null,
#Table VARCHAR(50)=Null,
#OrdrBy Varchar(40)=null
as
Begin
declare #TempCol nvarchar (100)
Exec(' SELECT '+#TempCol+' = '+#Col+' from ' + #Table +' order by '+#OrdrBy )
its showing error "Incorrect Syntax near '='
A little modification ...... Use TOP 1 in your select as if more than one value is returned by your select it will throw an error.
Use SYSNAME datatype for your Column names and table names.
Use QUOTENAME() function around your object name parameters, which puts square brackets [] around the passed parameter value and forces it to be treated as an object name (Protection against Sql Injection attack).
Use sp_executesql instead of EXEC and concatenating parameter values into string and executing again protects you against Sql Injection attack.
ALTER PROCEDURE Id_Fetch
#Col SYSNAME,
#Table SYSNAME,
#OrdrBy SYSNAME,
#Col_Value NVARCHAR(100) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Sql NVARCHAR(MAX);
SET #Sql = N' SELECT TOP 1 #Col_Value = ' + QUOTENAME(#Col)
+ N' FROM ' + QUOTENAME(#Table)
+ N' ORDER BY ' + QUOTENAME(#OrdrBy)
EXECUTE sp_executesql #Sql
,N'#Col_Value NVARCHAR(100) OUTPUT'
,#Col_Value OUTPUT
END
Anybody tell me what's wrong with creating this stored procedure.
CREATE PROC ImportData
AS
BEGIN
DECLARE #DatabasePath VARCHAR(MAX)
SET #DatabasePath = 'E:\ABC.xls'
DECLARE #sql nvarchar(MAX)
SET #sql = '
INSERT INTO [dbo].[Table_1]
SELECT *
FROM OPENROWSET(''Microsoft.Jet.OLEDB.4.0'',
''Excel 8.0;Database=' + #DatabasePath + ',
''SELECT * FROM [Sheet1$]'') AS xlsTable'
EXEC sp_executesql #sql
GO
END
ERROR:-
Incorrect syntax near '#sql'.
Msg 102, Level 15, State 1, Line 2
Incorrect syntax near 'END'.
Remove the GO from within the Stored Procedure
Something like
CREATE PROC ImportData
AS
BEGIN
DECLARE #DatabasePath VARCHAR(MAX)
SET #DatabasePath = 'E:\ABC.xls'
DECLARE #sql nvarchar(MAX)
SET #sql = '
INSERT INTO [dbo].[Table_1]
SELECT *
FROM OPENROWSET(''Microsoft.Jet.OLEDB.4.0'',
''Excel 8.0;Database=' + #DatabasePath + ',
''SELECT * FROM [Sheet1$]'') AS xlsTable'
EXEC sp_executesql #sql
END
You cannot have a batch terminator (GO) in the body of a stored procedure.