I want to use dynamic variable that is declared within dynamic SQL - sql

declare #sql as nvarchar(500)=''
set #sql='
declare #N4 as int = 1
declare #ms as nvarchar(100) = concat(''ms'', convert(nvarchar(10), #N4))
select #ms
'
exec #sql
I want output as ms1.
DECLARE #SQL AS NVARCHAR(500)=''
SET #sql='
while (#i <10)
begin
PRINT (''MS_''+#I)
set #i=#i+1
end
'
EXEC(#SQL)
not generating value for #i
i want to put this code in while loop as I want to access ms1 to ms10

Use sp_executesql which supports ouput params
DECLARE #MS VARCHAR(50)
exec sp_executesql N'declare #N4 as int = 1;
SELECT #MS= concat(''ms'', convert(nvarchar(10), #N4))',
N'#MS VARCHAR(50) output', #MS output;
SELECT #MS

Yes, you can use and for that you need to use sp_executesql like this -
Declare #sql as nvarchar(500)='', #Params NVARCHAR(500),
#N4 Int = 1, #ms nvarchar(100)
SET #Params = '#N4 Int, #ms nvarchar(100) OUTPUT'
set #sql= N'SELECT #ms = concat(''ms'', convert(nvarchar(10), #N4))'
EXEC SP_EXECUTESQL #sql, #Params, #N4 = #N4, #ms = #ms OUTPUT
SELECT #ms

Use While statement and string concatenation to get your result :
DECLARE #StartValue INT = 1
DECLARE #EndValue INT = 10
DECLARE #Query VARCHAR(500) = ''
WHILE #StartValue < #EndValue
BEGIN
SET #Query = #Query + 'sms_' + CAST(#StartValue AS VARCHAR) + ','
SET #StartValue = #StartValue + 1
END
SELECT Query

Related

Getting OUTPUT from Nested Dynamic SQL with a Remote Server

I am trying to execute some logic on a remote server using dynamic SQL, but when I set the dynamic SQL and try to call it nothing happens.. If I call the execution without making the execution dynamic it works without issue.
Not sure if what I am trying to do is allowed when passing OUTPUT values but figured I would see if anyone has any thoughts
DECLARE #sqlserver NVARCHAR(MAX) = ''
DECLARE #DBName NVARCHAR(MAX) = ''
DECLARE #parms NVARCHAR(MAX) = N'#output INT OUT', #output INT, #sql NVARCHAR(MAX) = '
;WITH DuplicateStatusCodes AS (
SELECT CodeTypeID FROM EDDSDBO.Code WHERE Name = ''Master'' OR Name = ''Unique'' OR Name = ''Duplicate''
)
SELECT ROW_NUMBER() OVER (ORDER BY CodeTypeID) RN, CodeTypeID INTO #temp
FROM DuplicateStatusCodes
GROUP BY CodeTypeID
HAVING COUNT(CodeTypeID) = 3
DECLARE #count INT = (SELECT COUNT(1) FROM #temp)
DECLARE #ctr INT = 1;
IF #count > 0
BEGIN
WHILE #ctr <= #count BEGIN
DECLARE #parms NVARCHAR(MAX) = N''#inneroutput INT OUT'';
DECLARE #inneroutput INT
DECLARE #codeartifact INT = (SELECT CodeTypeID FROM #temp WHERE RN <= 1 * #ctr and RN > 1 * (#ctr - 1))
DECLARE #duplicatestatuscheck NVARCHAR(MAX) = ''SELECT #inneroutput = COUNT(1) FROM eddsdbo.codeartifact_''+CAST(#codeartifact AS VARCHAR)+''''
EXEC sys.sp_executesql #duplicatestatuscheck, #parms, #inneroutput OUT
SELECT #output = #inneroutput
IF #inneroutput > 0
BREAK;
SET #ctr = #ctr + 1;
END
END
ELSE
BEGIN
SELECT #output = ''0''
END
'
DECLARE #linksql NVARCHAR(MAX) = '
DECLARE #sql NVARCHAR(MAX)
DECLARE #parms NVARCHAR(MAX) = N''#output INT OUT''
EXEC '+QUOTENAME(#sqlserver)+'.'+QUOTENAME(#DBName)+'.sys.sp_executesql #sql, #parms, #output = #output OUT'
--This does not work
EXEC sp_executesql #linksql, #parms, #output = #output
PRINT #output
--This works fine
EXEC [RemoteServerName].[DatabaseName].sys.sp_executesql #sql, #parms, #output = #output OUT ```
Appreciate any help
you would need to use OPENROWSET. Something like this:
DECLARE #ServerName VARCHAR(255) = '...'
,#DatabaseName VARCHAR(255) = '...'
,#Pwd VARCHAR(255) = '...'
,#UID VARCHAR(255) = '...'
,#Name VARCHAR(255) = 'Master'
DECLARE #connect varchar(max) = '''Server=' + #ServerName + ';database=' + #DatabaseName + ';Uid=' + #UID + ';Pwd=' + #Pwd + ';'''
declare #sqlstring varchar(max) = 'SET ANSI_NULLS OFF; SET ANSI_WARNINGS OFF;
SELECT CodeTypeID FROM EDDSDBO.Code WHERE Name = ''''' + #Name + ''''' '
declare #TheExecutableStr varchar(max) = '
SELECT *
FROM OPENROWSET(''SQLNCLI'', ' + #connect + ',
''' + #sqlstring + ''')'
SELECT #TheExecutableStr
--EXEC(#TheExecutableStr)
Please note you have to count single quote very diligently, hence SELECT #TheExecutableStr. It is for debugging purposes. You can view the query to be executed and actually copy/paste and execute before uncommenting last statement.
Hope it helps.
just noticed, you have sys.sp_executesql within sys.sp_executesql which might be problematic. you might need to find a way to refactor the code.

Variable in a dynamic query

I have a problem once I want to run the next query:
declare #j int = 1;
declare #column varchar(255);
set #column = 'last_name';
declare #tmp varchar(255);
declare #query nvarchar(255) = N'select ' + #column + N' from TEST where id = #j'
declare #tbl table(tmp varchar(255))
insert into #tbl
exec sp_executesql #query
select top 1 #tmp = tmp from #tbl
select #tmp
select * from #tbl;
The problem is that if I change the variable #j to a numeric value in the declaration of the #query variable, like this
declare #query nvarchar(255) = N'select ' + #column + N' from TEST where id = 1'
the query is running successfully, if I left the #j variable there, like this
declare #query nvarchar(255) = N'select ' + #column + N' from TEST where id = #j'
I got an error message:
"Must declare the scalar variable #j."
Why? And how can I solve that my query would work with the variable #j?
in the place of ==== where id = #j'
change like this may it works
Convert(nvarchar(2), #j);
You need to cast the #j variable to string. AS its type is INT you should cast it as
CAST(#j AS VARCHAR(12))
Also, you can pass parameters to dynamic SQL statement when it is executed using sp_executesql. In your case it will be something like this:
declare #j int = 1;
declare #column varchar(255);
set #column = 'last_name';
declare #tmp varchar(255);
declare #query nvarchar(255) = N'select ' + #column + N' from TEST where id = #j'
declare #tbl table(tmp varchar(255))
insert into #tbl
exec sp_executesql #query, N'#j INT', #j = #j
select top 1 #tmp = tmp from #tbl
select #tmp
select * from #tbl;
In the following line:
exec sp_executesql #query, N'#j INT', #j = #j
#query is your dynamic T-SQL statement
N'#j INT' is declaration of parameters
#j = #j is parameters assignments
sp_executsql documentation
You can use parameters in the sp_executesql statement like this:
CREATE TABLE TempTable (
TempID INT IDENTITY(1,1) NOT NULL,
SomeDescription VARCHAR(255) NOT NULL,
PRIMARY KEY(TempID))
INSERT INTO TempTable (SomeDescription)
VALUES ('Description 1'),
('Description 2'),
('Description 3')
DECLARE #sql NVARCHAR(500) = 'SELECT * FROM TempTable WHERE TempID = #TempVar',
#params NVARCHAR(500) = '#TempVar int',
#j INT = 2;
EXEC sp_executesql #sql, #params, #TempVar = #j;
declare #j int = 1;
declare #column varchar(255);
set #column = 'last_name';
declare #tmp varchar(255);
declare #query nvarchar(255) = N'select ' + #column + N' from TEST where id ='+ CAST(#j AS VARCHAR(5))
declare #tbl table(tmp varchar(255))
insert into #tbl
exec (#query)
select top 1 #tmp = tmp from #tbl
select #tmp
select * from #tbl;
enter code here

How to use Pass comma separated string in dynamic query in SQL

I have a function which will return integer values from comma delimited string , It takes two parameters (#string nvarchar(4000), #delimiter char(1)). So the problem is if I am using this function inside a dynamic query I am getting error , here is query
declare #ProductIDs varchar(11)
declare #SQL varchar(max)
set #ProductIDs='1,2,3,4'
declare #query varchar(max)
--set #query= #ProductIDs +','+#Delimiter
SELECT #SQL = 'SELECT val FROM dbo.[fnDelimitedStringToTable]('+ #ProductIDs +' , '','')'
Exec(#SQL)
I am getting error Procedure or function dbo.fnDelimitedStringToTable has too many arguments specified.
When you build a dynamic SQL like that, you need to wrap your parameter in double quote ''
declare #ProductIDs varchar(11)
declare #SQL varchar(max)
set #ProductIDs='1,2,3,4'
declare #query varchar(max)
--set #query= #ProductIDs +','+#Delimiter
SELECT #SQL = 'SELECT val FROM dbo.[fnDelimitedStringToTable]('''+ #ProductIDs +''' , '','')'
Exec(#SQL)
This way the SQL statement will be:
SELECT val FROM dbo.[fnDelimitedStringToTable]('1,2,3,4' , '','')
and not:
SELECT val FROM dbo.[fnDelimitedStringToTable](1,2,3,4 , '','')
Use sp_executesql instead. In this case you can pass arguments as parameters.
DECLARE #SQL nvarchar(max)
DECLARE #ParmDef nvarchar(1000)
DECLARE #ArgProductIDs nvarchar(100)
DECLARE #Arg2 nvarchar(100)
DECLARE #Arg3 nvarchar(100)
SET #SQL = N'SELECT val
FROM dbo.[fnDelimitedStringToTable](#ProductIDs, #Param2, #Param3)';
SET #ParmDef = N'#ProductIDs nvarchar(100),
#Param2 nvarchar(100),
#Param3 nvarchar(100)';
SET #Arg1 = N'1,2,3,4';
SET #Arg2 = N'';
SET #Arg3 = N'';
EXEC sp_executesql #SQL, #ParmDef,
#ProductIDs = #ArgProductIDs, #Param2 = #Arg2, , #Param3 = #Arg3

Conversion failed while converting nvarchar value to datatype int

I want to get the values of #sql to p.
But while conversion it says that "Conversion failed when converting the nvarchar value 'select sum(stock) from[Hard disk]' to data type int."
declare #tname varchar(10);
declare #p int
declare #i int
declare #sql nvarchar(max);
set #tname = 'Hard disk';
set #sql = 'select sum(stock) from' + '[' + #tname + ']'
exec (#sql)
print #sql
select #p = convert(int,#sql)
print #p
What i want is to assign the result of the query #SQL in integer variable #p..
One way to do it is do it all in the dynamic sql.
declare #tname varchar(10);
declare #p int
declare #i int
declare #sql nvarchar(max);
set #tname = 'Hard disk';
set #sql =
'DECLARE #Result AS INT
select #Result = sum(stock) from' + '[' + #tname + ']
PRINT #Result'
exec (#sql)
The other way would be creating an output param.
DECLARE #tname VARCHAR(50)
DECLARE #SQLString NVARCHAR(500)
DECLARE #ParmDefinition NVARCHAR(500)
DECLARE #Result INT
SET #tname = 'Hard disk';
SET #SQLString = N'SELECT #Result = sum(stock)
FROM ' + QUOTENAME( #tname )
SET #ParmDefinition = N'#Result INT OUTPUT'
EXECUTE sp_executesql
#SQLString,
#ParmDefinition,
#Result=#Result OUTPUT
PRINT #Result
You better use QUOTENAME for embrasing the table name with the brackets, as it is more native.
declare #p int;
EXEC SP_EXECUTESQL N'select #p = sum(stock) from '[' + #tname + ']',N'#p int OUTPUT',#p OUTPUT;
select #p

Get SQL result into variable

Here is what I have so far. I want to store the query result into an int variable but I get null so far. After execute, both #query and #countrow are both null. Any suggestion would be great.
SET #query = N'select #countrow=count(*) from ' + #tablename
EXECUTE sp_executesql #query
DECLARE #i INT, #sql NVARCHAR(512), #tablename varchar(200) = 'tbl'
SET #sql = N'SELECT #i = COUNT(*) FROM ' + #tablename
EXEC sp_executesql
#query = #sql,
#params = N'#i INT OUTPUT',
#i = #i OUTPUT
PRINT #i
Take a look at SQL Fiddle
You need to use the OUTPUT keyword, similar to this:
declare #query nvarchar(max)
declare #countrow int
declare #tablename varchar(50)
SET #query = N'select #cnt=count(*) from ' + #tablename
EXECUTE sp_executesql #query, N'#cnt int OUTPUT', #cnt=#countrow OUTPUT
select #countrow as countrow -- to get the result