MS SQL - Where are the syntax and scalar errors? - sql-server

I've been beating my head over this brick wall all morning. This is a very simplified example of the error(s) I've been receiving. I am using SSMS.
DECLARE #myid nvarchar(10) = '5'
DECLARE #sql nvarchar(2048) = 'SELECT id FROM Applications A WHERE A.id=#myid'
EXECUTE sp_executesql #sql, #myid=#myid
Errors:
Msg 102, Level 15, State 1, Line 1 Incorrect syntax near '5'. Msg 137,
Level 15, State 2, Line 1 Must declare the scalar variable "#myid".
Why am I getting the syntax, and scalar errors? #myid is defined, right?

sp_executesql needs to receive a definition of the parameters, which you are missing. So, in your case, you should use:
DECLARE #myid nvarchar(10) = '5';
DECLARE #sql nvarchar(2048) = 'SELECT id FROM Applications A WHERE A.id=#myid';
EXECUTE sp_executesql #sql, N'#myid nvarchar(10)', #myid=#myid;

Related

sp_executesql reports: Incorrect syntax near #sequenceName

My requirement is to retrieve into a variable, the next value for a sequence, the name of which is derived from a string and a value.
When I run the following as a test using exec sp_executesql ... an error is reported:
Incorrect syntax near #sequenceName
What's wrong with my code?
DECLARE #nextSeqID varchar(10);
DECLARE #sql nvarchar(100);
DECLARE #eqtypeID int;
DECLARE #sequence nvarchar(50);
DECLARE #paramdef nvarchar(100);
SET #eqtypeID = 7;
SET #sequence = 'dbo.seq_eqtype_autoserno_' + CAST(#eqtypeID as nvarchar(8));
-- #sequence = dbo.seq_eqtype_autoserno_7
SET #sql = N'SELECT #nextSeqID_OUT = NEXT VALUE FOR #sequenceName';
-- #sql = SELECT #nextSeqID_OUT = NEXT VALUE FOR #sequenceName
SET #paramdef = N'#nextSeqID_OUT varchar(10) OUTPUT, #sequenceName nvarchar(50)';
-- #paramdef = #nextSeqID_OUT varchar(10) OUTPUT, #sequenceName nvarchar(50)
EXEC sp_executesql #sql, #paramdef, #sequenceName = #sequence, #nextSeqID_OUT = #nextSeqID OUTPUT;
/*
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '#sequenceName'.
*/
It is admirable and correct that you are using sp_executesql to pass dynamic things through variables. However, you can not do this with object names(like a sequence) and other stuff which are required by the query at runtime.
Remove #sequenceName from the parameters and the definition, and put it directly on the code. The correct way to do this to still be safe from injection is to use it within quotename, so whatever injection attack happens, it will be quoted, and thus safe:
SET #sql = N'SELECT #nextSeqID_OUT = NEXT VALUE FOR '+quotename(#sequenceName);
SET #paramdef = N'#nextSeqID_OUT varchar(10) OUTPUT';
EXEC sp_executesql #sql, #paramdef, #nextSeqID_OUT = #nextSeqID OUTPUT;

Syntax error escaping string in SQL Server stored procedure

I am new to SQL Server 2012 and have read in lots of places that we only need to escape the single-quote character, by doubling it up. In most cases this seems to work for me, but I am having particular trouble with the following simple stored procedure:
DECLARE #SQLStr nvarchar(max)
DECLARE #SQLParam nvarchar(max)
DECLARE #SQLParamValues nvarchar(max)
SET #SQLStr = 'UPDATE test_data SET name=#1,name_reservation_date=#2 WHERE id=#3'
SET #SQLParam = '#1 nvarchar(50),#2 datetime2(0),#3 bigint'
SET #SQLParamValues = '#1=N''b''1'',#2=''2014-4-25 12:09:39'',#3=12345'
EXEC( 'EXECUTE sp_executesql N''' + #SQLStr + ''', N''' + #SQLParam + ''', ' + #SQLParamValues)
The error that I am getting is this:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '1'.
Msg 105, Level 15, State 1, Line 1
Unclosed quotation mark after the character string ',#3=12345'.
And the problem is that I am trying to write the value b'1, which I have escaped as b''1. If I write just b1 then there is no problem.
The syntax error is on the last line - i.e. when trying to use the #SQLParamValues string as an argument to my EXEC call.
But I can't see any unclosed quotation mark, can someone help me out? Is there a better approach that I should be taking, to avoid all of these doubling-up of quotes? I've inherited this system from someone else so I'm not entirely convinced at this stage.
You don't need to wrap sp_executesql in another EXEC. Use the syntax below. Note that the parameters' values are passed without a variable:
DECLARE #SQLStr nvarchar(max)
DECLARE #SQLParam nvarchar(max)
SET #SQLStr = N'UPDATE test_data SET name=#1,name_reservation_date=#2 WHERE id=#3'
SET #SQLParam = N'#1 nvarchar(50),#2 datetime2(0),#3 bigint'
EXECUTE sp_executesql #SQLStr, #SQLParam,
#1=N'b''1',#2='2014-4-25 12:09:39',#3=12345

Msg 102, Level 15, State 1, Line 3 Incorrect syntax near ' '

I wrote the following code:
Declare #DaataBaseName2 varchar(50)
set #DaataBaseName2 = 'LUNDB14644A01' -- #DaataBaseName
USE #DaataBaseName2 --LUNDB14644A01
GO
I received following error:
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near '#DaataBaseName2'.
Why?
You will have to execute your code via dynamic SQL. You have to be careful with dynamic sql as it can lead to sql injection attack.
Here is a small scale sample of how to use a dynamic database.
Declare #DaataBaseName2 varchar(50),
#sql nvarchar(Max)
set #DaataBaseName2 = 'master' -- #DaataBaseName
set #sql = 'USE ' + #DaataBaseName2 + ';' + CHAR(13)
SET #sql = #sql + 'SELECT db_name()'
exec sp_executesql #sql
GO

How to assign a value to variable using Sql String

I would like to assign a select value to a variable using sql string. Below is my code:
DECLARE #maxRow INT, #tableName NVARCHAR(128) = N'whatever';
select #maxRow=Max(id) from #tableName
But this throws an error:
Msg 1087, Level 16, State 1, Line 3
Must declare the table variable "#tableName".
Even though I did declare the variable.
You can't use a variable for a table name unless you put it into dynamic SQL. The code is currently expecting #tableName to be a table variable, not a string, though it's clear from your syntax this is not what you intended. This usage smells like sub-optimal design and lends itself to significant SQL injection risks, but you can try this code instead:
DECLARE #maxRow INT;
DECLARE #sql NVARCHAR(MAX) = N'SELECT #maxRow = MAX(id) FROM '
+ QUOTENAME(#tableName) + ';';
EXEC sp_executesql #sql, N'#maxRow INT OUTPUT', #maxRow OUTPUT;
PRINT #maxRow;
Please do read up on SQL injection and normalization.

Dynamically adding column to the temptable?

In my sqluery, i am trying to add columns dynamically, but it is showing error Like:
Msg 214, Level 16, State 2, Procedure sp_executesql, Line 1
Procedure expects parameter '#statement' of type 'ntext/nchar/nvarchar'.
this is my proc
declare #curntyear int
declare #pasyear int
declare #sql nvarchar(max)
declare #temp varchar(50)
select #pasyear=YEAR( DATEADD (YEAR,-3,GETDATE ()))
select #curntyear =YEAR (getdate())
print #pasyear
print #curntyear
create table #TempTable (years varchar(30))
insert into #TempTable select (cargo+port+railway+estate)as 'sum' from operatingincome where YEAR(createddate)=#pasyear
while (#curntyear >=#pasyear )
begin
set #pasyear =#pasyear +1
--select #temp=(cargo+port+railway+estate)as 'sum' from operatingincome where YEAR(createddate)=#pasyear
select #temp= convert(varchar,(cargo+port+railway+estate),106) from operatingincome where YEAR(createddate)= #pasyear
set #sql ='alter table #TempTable add '+ CONVERT(varchar,#pasyear,106)+' varchar(50)'
exec sp_executesql #sql
print #sql
set #sql = 'update #TempTable set '+CONVERT(varchar,#pasyear,106) +'='+#temp +' where years='''+CONVERT(varchar,#pasyear,106)+''
exec sp_executesql #sql
set #temp =''
end
select * from #TempTable
i am getting error like this :
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '2009'.
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '2010'.
alter table #TempTable add 2010 varchar(50)
update #TempTable set 2010=9300 where years=2010
Sounds like you're calling sp_executesql with a VARCHAR statement, when it needs to be NVARCHAR.
e.g. This will give the error because #SQL needs to be NVARCHAR
Declare your variable #sql varchar to nvarchar, that will work fine:
declare #sql nvarchar(max)
UPdate:
Change your sql setting as below: you need to use [] in column name as [ColumName]
set #sql ='alter table #TempTable add ['+ CONVERT(varchar,#pasyear,106)+'] varchar(50)'
set #sql = 'update #TempTable set ['+CONVERT(varchar,#pasyear,106) +']='+#temp +' where years='''+CONVERT(varchar,#pasyear,106)+''
Change
declare #sql varchar(max)
to be
declare #sql nvarchar(max)
You are told this in the error message and on MSDN (my bold)
[ #statement= ] statement
Is a Unicode string that contains a Transact-SQL statement or batch. statement must be either a Unicode constant or a Unicode variable.

Resources