sp_executesql reports: Incorrect syntax near #sequenceName - sql-server

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;

Related

Getting Empty Output

Iam trying to Execute Dynamic Query, But Iam getting Empty Output.Where I'm Wrong?
SET #SQL=N'
SELECT GETDATE(),'+#AMUID+','+ #BNO +
',LOT,BARCODEID,'+#ACTWT+',TARE_QUANTITY,''NA'',STAGE,0,0,0,
'+ #UNAME+ ','+#PR + ',GETDATE()
FROM DISPENSE_HOLD_START WHERE BATCH_NO='''+#BNO+''' AND BARCODEID='''+
#BARID +''' and IS_OUT=0';
PRINT(#SQL)
Here #AMUID,#BNO,#ACTWT etc are Input Parameters Declared with NVARCHAR(MAX) data type.They are dynamic Iam getting nothing When I Print this.
as you are not executing the query but printing it
this is same as
3+3=6 and "3"+"3"="33"
the dynamic queries are typically executed like this(simplest method)
DECLARE #IntVariable int;
DECLARE #SQLString nvarchar(500);
DECLARE #ParmDefinition nvarchar(500);
/* Build the SQL string one time.*/
SET #SQLString =
N'SELECT BusinessEntityID, NationalIDNumber, JobTitle, LoginID
FROM AdventureWorks2012.HumanResources.Employee
WHERE BusinessEntityID = #BusinessEntityID';
SET #ParmDefinition = N'#BusinessEntityID tinyint';
/* Execute the string with the first parameter value. */
SET #IntVariable = 197;
EXECUTE sp_executesql #SQLString, #ParmDefinition,
#BusinessEntityID = #IntVariable;
/* Execute the same string with the second parameter value. */
SET #IntVariable = 109;
EXECUTE sp_executesql #SQLString, #ParmDefinition,
#BusinessEntityID = #IntVariable;
Case#1 :
In your Above Query, You are using PRINT instead of EXEC. So Make sure you are executing the Query in your actual Code
EXEC(#SQL)
Case#2 :
If you are executing this, there is a possibility that if any of the Parameter Value is NULL, then the entire String will become NULL
If you add any Value to NULL the Result will be NULL
SELECT
'ABC',
'ABC'+NULL
Gives Me this
So Use ISNULL
SET #SQL = N'
SELECT
GETDATE(),
'+ISNULL(#AMUID,'')+','+ISNULL(#BNO,'')+',LOT,
BARCODEID,'+ISNULL(#ACTWT,'')+',TARE_QUANTITY,''NA'',STAGE,0,0,0,
'+ISNULL(#UNAME,'')+','+ISNULL(#PR,'')+',GETDATE()
FROM DISPENSE_HOLD_START
WHERE BATCH_NO='''+ISNULL(#BNO,'')+'''
AND BARCODEID='''+ISNULL(#BARID,'')+'''
and IS_OUT=0';
EXEC(#SQL);
Case#3
Looking at your Code, I think you don't need a Dynamic SQL here. Instead, you can directly go Like this
SELECT
GETDATE(),
#AMUID,
#BNO,
LOT,
BARCODEID,
#ACTWT,
TARE_QUANTITY,
'NA',
STAGE,
0,
0,
0,
#UNAME,
#PR,
GETDATE()
FROM DISPENSE_HOLD_START
WHERE BATCH_NO = #BNO
AND BARCODEID = #BARID
AND IS_OUT = 0
Works just fine for me
declare #val nvarchar(100) = 'tommy can you see me'
declare #SQL nvarchar(100) = N'SELECT GETDATE(), ''' + #val + '''';
PRINT(#SQL);

SQL Server incorrect syntax exception when executing with sp_executesql

I am calling a procedure from a trigger and passing some parameters from trigger to procedure. Parameters are:
#table_name varchar(128), #where_str varchar(200)
Inside the procedure, I'm executing a command with sp_executesql. I think, I am using incorrect syntax, but I couldn't find the resolution.
This is the executed query:
SET #SqlString = N'update #ptable_name set RepSt=2 #pwhere_str';
SET #ParmDefinition = N'#ptable_name varchar(128), #pwhere_str varchar(200)';
execute sp_executesql #SqlString, #ParmDefinition,
#ptable_name = #table_name, #pwhere_str = #where_str;
Passed parameters are like that:
#table_name is [MyTable]
#where_str = N'where MyColumnA = '+#oldMyColumnA+N' AND MyColumnB = '+#oldMyColumnB+N' AND MyColumnC = '+#oldMyColumnC;
What you end up executing is something like:
DECLARE #ptable_name VARCHAR(128) = 'your_Table'
, #pwhere_str VARCHAR(200) = 'Your_where_clause'
UPDATE #ptable_name
SET RepSt=2
WHERE #pwhere_str
This doesn't work, you need to replace the variable in the executed sql:
SET #SqlString = N'update #ptable_name set RepSt=2 #pwhere_str';
SET #SqlString = REPLACE(REPLACE(#SqlString, '#ptable_name', #table_name), '#pwhere_str', #where_str)
execute sp_executesql #SqlString
(Very dirty, but this is the idea.)
SET #SqlString =N'update ' + #ptable_name + ' set RepSt=2 #pwhere_str';

Must Declare Scalar variable #nRuleId

USE GDMDBNS_1720
GO
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_TYPE = 'PROCEDURE'
AND ROUTINE_SCHEMA = 'dbo' AND ROUTINE_NAME = 'usp_RmsExecuteValidationRule')
BEGIN
DROP PROCEDURE dbo.usp_RmsExecuteValidationRule
END
GO
Create PROCEDURE [dbo].[usp_RmsExecuteValidationRule]
#nRuleId INT,
#FIPSName VARCHAR(5)
AS
BEGIN
DECLARE #strRuleQuery VARCHAR(MAX)
DECLARE #sqlstat AS NVARCHAR(MAX)
DECLARE #params AS NVARCHAR(MAX)
SET #strRuleQuery = N'SELECT RULE_QUERY from GdmValidationRuleMaster where
RULE_ID = #nRuleId'
SET #sqlstat = #strRuleQuery
SET #params = N'#FIPSName VARCHAR(5)'
EXEC sp_executesql #params,
#query = #sqlstat,
#FIPSName = #FIPSName
END
got error while Debugging must declare scalar variable #nRuleId . I have already declared. But error is pooping out always.
There appear to be a number of issues with the code, as is.
To return a value, you need to declare an OUTPUT parameter and the variable #FIPSName is not actually used in the code, and #strRuleQuery is superfluous in this code.
Here is the code from inside the SProc, that should be closer to your needs.
-- Parameters
DECLARE
#nRuleId INT = 1,
#FIPSName VARCHAR(5) = 'ITS'
-- Local variables
DECLARE #sqlstat AS NVARCHAR(MAX)
DECLARE #params AS NVARCHAR(MAX)
DECLARE #RULE_QUERY NVARCHAR(MAX)
SET #sqlstat = N'SELECT #RULE_QUERY=RULE_QUERY from GdmValidationRuleMaster where RULE_ID = #nRuleId'
SET #params = N'#nRuleId INT, #RULE_QUERY NVARCHAR(MAX) OUTPUT'
EXEC sp_executesql
#sqlstat,
#params,
#nRuleId = #nRuleId, #RULE_QUERY= #RULE_QUERY OUTPUT
-- Output
SELECT #RULE_QUERY
You must rewrite execution part:
SET #params = N'#FIPSName VARCHAR(5), #nRuleId int'
EXEC sp_executesql #strRuleQuery, #params, #FIPSName = #FIPSName, #nRuleId = #nRuleId
I don't understand, why do you pass #FIPSName as parameter, it is not used in your batch.

Nested sp_executesql not working with output variable

I am trying to call a stored procedure (with output variable) using sp_executesql but within another stored procedure. I wrote the following, but still not able to get trhough what that error means
This would be called from webservice code:
exec sp1 'obj1',#params
Here obj and params are of nvarchar(max)
Definition of sp1 is :
Alter procedure [dbo].[sp1 ]
#procname nvarchar(max),
#params nvarchar(max)
as
declare #temp varchar(15)
if #procname = 'obj1'
begin
set #params = #params + ',#Newval varchar(15) output'
EXEC sp_executesql #sp2,#params,#Newval=#temp OUTPUT
end
Definition of sp2:
Here I am returning #Newval
Error I am getting :
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ','.
Also in 2 in place of exec statement , I have tried following:
EXEC sp_executesql #sp2, #params, #temp OUTPUT;
Results in the same error.
set #sql='sp2,' + ' #params ' + ',#params,#temp OUTPUT'
EXEC sp_executesql (#sql)
Also results in the same error.
I need this dynamic selection of stored procedures in sp1 and params is a nvarchar(max) string of parameters and their values, some of them are varchar and are embedded in ''value'' format but this string is fine as I am able to call the underlying sp2 with this.
Additional info, it it helps.
EXEC sp_executesql #sp2,#params,#Newval=#temp OUTPUT
in this #params is combination of keys and vlaue pairs for the final sp. something like :
'#key1="a",#key2="b"'
and so on, I can not predefined the #params but it is dynamic and it is working
fine when I run it with
exec (#sql)
Format while whole of the name, params are embedded in the #sql
If #params='' or NULL then your , before #Newval is irrelevant. I suggest you to check:
IF NULLIF(#params,'') IS NULL or #params IS NULL
SET #params = '#Newval varchar(15) output'
ELSE
SET #params = #params + ',#Newval varchar(15) output'
You are passing #sp2 maybe you need this:
ALTER PROCEDURE [dbo].[sp1]
#procname nvarchar(max),
#params nvarchar(max)
AS
DECLARE #temp varchar(15)
IF #procname = 'obj1'
BEGIN
SET #params = #params + ',#Newval varchar(15) output'
EXEC sp_executesql N'EXEC sp2 #someparam1, #someparam2, #Newval varchar(15) OUTPUT', #params, #someparam1 = 1, #someparam2 = 2, #Newval=#temp OUTPUT
END
EDIT
Working example:
USE [AdventureWorks]
GO
DECLARE #procname nvarchar(max) = 'EXEC [dbo].[uspGetWhereUsedProductID] #StartProductID, #CheckDate',
#params nvarchar(max) = '#StartProductID int, #CheckDate date'
EXEC sp_executesql #procname, #params, #StartProductID = 1, #CheckDate = '2015-10-17'
GO

How do you use OPENQUERY within sp_executesql?

I'm trying to verify a job number exists on a linked server and get back a variable (#JobExists) indicating whether it does or not (1 for yes, 0 for no).
To do this I'm trying to use OPENQUERY along with sp_executesql as I have to pass in a parameter for the job number. I've tried the code below but get the error 'Procedure expects parameter '#statement' of type 'ntext/nchar/nvarchar'. For testing purposes I've declared and set the variable #JobNumber.
DECLARE #JobNumber as varchar(50)
SET #JobNumber = '2112111'
DECLARE #JobExists as BIT
DECLARE #JobCount as int
DECLARE #ParmDefinition as varchar(100)
DECLARE #sql as varchar(500)
SET #JobExists = 0
SET #ParmDefinition = N'#Result int output'
SET #sql = 'SELECT #Result = SELECT COUNT(*) FROM OPENQUERY(MYLINKEDSVR,''SELECT JOB_NUMBER FROM PROD.tbl1 WHERE JOB_NUMBER = ''''' + UPPER(RTRIM(LTRIM(#JobNumber))) + ''''''')'
exec sp_executesql #sql, #ParmDefinition, #Result = #JobCount output
IF #JobCount > 0
SET #JobExists = 1
SELECT #JobExists
I've read up sp_executesql here: http://technet.microsoft.com/en-us/library/ms188001.aspx
I've also done various searches but haven't come across any answers that work for me.
Is there something I'm missing?
The error message is clear: you must declare #sql as nvarchar and not as varchar.
The same for #ParamDefinition:
DECLARE #ParmDefinition as nvarchar(100)
DECLARE #sql as nvarchar(500)

Resources