declare variable in a table in SQL - sql-server

I have a below query that requires help
Declare #DB varchar(3)
set #DB = 'C01'
SELECT * FROM SVBNORD+#DB WHERE ORDER_DATE = ''
But I get a message
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near '+'.
Can you please help me correct my statement.

You should use execute to dynamically call the query:
Declare #DB varchar(3)
set #DB = 'C01'
execute ('SELECT * FROM SVBNORD'+#DB+' WHERE ORDER_DATE = '''' ')

You can't do this in normal sql. You can however build up sql dynamically and execute it, like so:
DECLARE #sql NVARCHAR(MAX);
SET #sql =
'SELECT * FROM SVBNORD' + #DB + N'WHERE ORDER_DATE = ''''';
EXEC(#sql);
You'll need to double up any single quotes in the query.

Related

Invalid column name when using dynamic SQL

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

Issues encountered with dynamic SQL

ALTER PROCEDURE [dbo].[Create_Subjects]
#Subj_ID nvarchar(9)
AS
DECLARE #First3Digits nvarchar(3);
DECLARE #Result int;
DECLARE #Sql nvarchar(max)
-- Fetching the fiest 3 digits of the subject
SET #First3Digits = SUBSTRING(#Subj_ID,1,3);
-- Check if view is present or not
IF EXISTS (SELECT 1 FROM sys.views WHERE Name = #First3Digits)
BEGIN
SET #Sql = 'select #Result = case when exists (select 1 from dbo.' + quotename(#First3Digits) + ' where SubjectName = ''' + #Subj_ID + ''') then 1 else 0 end';
EXECUTE sp_executesql #Sql, N'#Subj_ID nvarchar(9), #Result bit out', #Subj_ID = #Subj_ID, #Result = #Result out;
-- checking if the subject is present in the view
END
ELSE
BEGIN
-- Create a view as view doesn't exist
SET #Sql = 'create view ' + #First3Digits
+ ' as
(select SubjectName from dbo.Subjects where SubjectName like '+#First3Digits+'%'+');';
EXECUTE sp_executesql #Sql, N'#First3Digits nvarchar(3)', #First3Digits= #First3Digits;
SET #Result = 0;
END
RETURN #Result
GO
This is the code for executing the stored procedure:
EXEC [dbo].[Create_Subjects] '1234567890'
Error encountered:
Msg 156, Level 15, State 1, Line 28
Incorrect syntax near the keyword 'view'
Msg 102, Level 15, State 1, Line 29
Incorrect syntax near ')'
There are a number of issues with your SQL. But firstly the way to debug them is to print the SQL without executing it, then its normal SQL and you can easily identify what is wrong with it.
No brackets are allowed around the SQL making up the view.
You have to quote your strings as per normal, which means doubling up the quotes in the dynamic string.
Use quotename again as suggested in the comments.
There is no need to pass the parameter #First3Digits into sp_executesql because by that point you've used its value - which you have to do given you are creating a view.
set #Sql = 'create view dbo.' + quotename(#First3Digits)
+ ' as'
+ ' select SubjectName'
+ ' from dbo.Subjects'
+ ' where SubjectName like ''' + #First3Digits + ''' + ''%'';';
-- This is how you debug dynamic SQL
print(#Sql);
execute sp_executesql #Sql;
Note: As I mentioned in your previous question, with the information provided, this seems to be a really bad design. There is almost certainly a better way to solve your bigger picture problem. As commented by Martin Smith an Inline Table Valued Function might be worth investigating.

Column name not working when placed inside a variable in SQL Server [duplicate]

create procedure sp_First
#columnname varchar
AS
begin
select #columnname from Table_1
end
exec sp_First 'sname'
My requirement is to pass column names as input parameters.
I tried like that but it gave wrong output.
So Help me
You can do this in a couple of ways.
One, is to build up the query yourself and execute it.
SET #sql = 'SELECT ' + #columnName + ' FROM yourTable'
sp_executesql #sql
If you opt for that method, be very certain to santise your input. Even if you know your application will only give 'real' column names, what if some-one finds a crack in your security and is able to execute the SP directly? Then they can execute just about anything they like. With dynamic SQL, always, always, validate the parameters.
Alternatively, you can write a CASE statement...
SELECT
CASE #columnName
WHEN 'Col1' THEN Col1
WHEN 'Col2' THEN Col2
ELSE NULL
END as selectedColumn
FROM
yourTable
This is a bit more long winded, but a whole lot more secure.
No. That would just select the parameter value. You would need to use dynamic sql.
In your procedure you would have the following:
DECLARE #sql nvarchar(max) = 'SELECT ' + #columnname + ' FROM Table_1';
exec sp_executesql #sql, N''
Try using dynamic SQL:
create procedure sp_First #columnname varchar
AS
begin
declare #sql nvarchar(4000);
set #sql='select ['+#columnname+'] from Table_1';
exec sp_executesql #sql
end
go
exec sp_First 'sname'
go
This is not possible. Either use dynamic SQL (dangerous) or a gigantic case expression (slow).
Create PROCEDURE USP_S_NameAvilability
(#Value VARCHAR(50)=null,
#TableName VARCHAR(50)=null,
#ColumnName VARCHAR(50)=null)
AS
BEGIN
DECLARE #cmd AS NVARCHAR(max)
SET #Value = ''''+#Value+ ''''
SET #cmd = N'SELECT * FROM ' + #TableName + ' WHERE ' + #ColumnName + ' = ' + #Value
EXEC(#cmd)
END
As i have tried one the answer, it is getting executed successfully but while running its not giving correct output, the above works well
You can pass the column name but you cannot use it in a sql statemnt like
Select #Columnname From Table
One could build a dynamic sql string and execute it like EXEC (#SQL)
For more information see this answer on dynamic sql.
Dynamic SQL Pros and Cons
As mentioned by MatBailie
This is much more safe since it is not a dynamic query and ther are lesser chances of sql injection . I Added one situation where you even want the where clause to be dynamic . XX YY are Columns names
CREATE PROCEDURE [dbo].[DASH_getTP_under_TP]
(
#fromColumnName varchar(10) ,
#toColumnName varchar(10) ,
#ID varchar(10)
)
as
begin
-- this is the column required for where clause
declare #colname varchar(50)
set #colname=case #fromUserType
when 'XX' then 'XX'
when 'YY' then 'YY'
end
select SelectedColumnId from (
select
case #toColumnName
when 'XX' then tablename.XX
when 'YY' then tablename.YY
end as SelectedColumnId,
From tablename
where
(case #fromUserType
when 'XX' then XX
when 'YY' then YY
end)= ISNULL(#ID , #colname)
) as tbl1 group by SelectedColumnId
end
First Run;
CREATE PROCEDURE sp_First #columnname NVARCHAR(128)--128 = SQL Server Maximum Column Name Length
AS
BEGIN
DECLARE #query NVARCHAR(MAX)
SET #query = 'SELECT ' + #columnname + ' FROM Table_1'
EXEC(#query)
END
Second Run;
EXEC sp_First 'COLUMN_Name'
Please Try with this.
I hope it will work for you.
Create Procedure Test
(
#Table VARCHAR(500),
#Column VARCHAR(100),
#Value VARCHAR(300)
)
AS
BEGIN
DECLARE #sql nvarchar(1000)
SET #sql = 'SELECT * FROM ' + #Table + ' WHERE ' + #Column + ' = ' + #Value
--SELECT #sql
exec (#sql)
END
-----execution----
/** Exec Test Products,IsDeposit,1 **/

Dynamic SQL is correct, but SP_EXECUTESQL will not execute it?

The following code execute SQL n times.
PRINT 'X'
GO 10
I try to make this a dynamic codes with following query -
DECLARE #rows int
DECLARE #sql nvarchar(max)
SET #rows = 10
SET #sql =
'INSERT INTO MultiInsert(Name)
VALUES(NULL)
GO ' + CAST(#rows as NVARCHAR(50))
PRINT #sql
EXEC SP_EXECUTESQL #sql
The SQL is a correct, but SP_EXECUTESQL give me an error as show below -
INSERT INTO MultiInsert(Name)
VALUES(NULL)
GO 10
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near 'GO'.
How do I fix this error ?
You can't use GO in dynamic SQL expressions. GO is a keyword for management studio or other client tools.
Here's the MSDN documentation about GO, which explains how it's a client keyword only: http://technet.microsoft.com/en-us/library/ms188037.aspx. Notice this line in particular: "Applications based on the ODBC or OLE DB APIs receive a syntax error if they try to execute a GO command. The SQL Server utilities never send a GO command to the server."
Well, #siride's answer shows you why it fails, and this is how you can fix it:
DECLARE #rows int
DECLARE #sql nvarchar(max)
SET #rows = 10
SET #sql =
'DECLARE #I INT = 0
WHILE #I <= ' + CAST(#rows as NVARCHAR(50)) + '
BEGIN
INSERT INTO MultiInsert(Name)
VALUES(NULL)
SET #I = #I + 1
END'
PRINT #sql
EXEC SP_EXECUTESQL #sql
You can use this kind of query to generate 10 NULLs in one run:
WITH mycte AS
(
SELECT NULL as VAL
UNION ALL
SELECT NULL FROM mycte
)
SELECT TOP 10 Val from mycte
So you would do something like
DECLARE #rows int
DECLARE #sql nvarchar(max)
SET #rows = 10
SET #sql =
'WITH mycte AS
(
SELECT NULL as VAL
UNION ALL
SELECT NULL FROM mycte
)
INSERT INTO MultiInsert(Name)
SELECT TOP ' + CAST(#rows as NVARCHAR(50)) + ' Val from mycte'
EXEC SP_EXECUTESQL #sql
In this case a recursive CTE with a single insert is used instead of a loop.

Error in Creating stored procedure

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.

Resources