Variable in a dynamic query - sql

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

Related

How to get dynamic SQL query output into declared variable in SQL Server? [duplicate]

I have a piece of dynamic SQL I need to execute, I then need to store the result into a variable.
I know I can use sp_executesql but can't find clear examples around about how to do this.
If you have OUTPUT parameters you can do
DECLARE #retval int
DECLARE #sSQL nvarchar(500);
DECLARE #ParmDefinition nvarchar(500);
DECLARE #tablename nvarchar(50)
SELECT #tablename = N'products'
SELECT #sSQL = N'SELECT #retvalOUT = MAX(ID) FROM ' + #tablename;
SET #ParmDefinition = N'#retvalOUT int OUTPUT';
EXEC sp_executesql #sSQL, #ParmDefinition, #retvalOUT=#retval OUTPUT;
SELECT #retval;
But if you don't, and can not modify the SP:
-- Assuming that your SP return 1 value
create table #temptable (ID int null)
insert into #temptable exec mysp 'Value1', 'Value2'
select * from #temptable
Not pretty, but works.
DECLARE #vi INT
DECLARE #vQuery NVARCHAR(1000)
SET #vQuery = N'SELECT #vi= COUNT(*) FROM <TableName>'
EXEC SP_EXECUTESQL
#Query = #vQuery
, #Params = N'#vi INT OUTPUT'
, #vi = #vi OUTPUT
SELECT #vi
DECLARE #tab AS TABLE (col1 VARCHAR(10), col2 varchar(10))
INSERT into #tab EXECUTE sp_executesql N'
SELECT 1 AS col1, 2 AS col2
UNION ALL
SELECT 1 AS col1, 2 AS col2
UNION ALL
SELECT 1 AS col1, 2 AS col2'
SELECT * FROM #tab
Return values are generally not used to "return" a result but to return success (0) or an error number (1-65K). The above all seem to indicate that sp_executesql does not return a value, which is not correct. sp_executesql will return 0 for success and any other number for failure.
In the below, #i will return 2727
DECLARE #s NVARCHAR(500)
DECLARE #i INT;
SET #s = 'USE [Blah]; UPDATE STATISTICS [dbo].[TableName] [NonExistantStatisticsName];';
EXEC #i = sys.sp_executesql #s
SELECT #i AS 'Blah'
SSMS will show this
Msg 2727, Level 11, State 1, Line 1
Cannot find index 'NonExistantStaticsName'.
If you want to return more than 1 value use this:
DECLARE #sqlstatement2 NVARCHAR(MAX);
DECLARE #retText NVARCHAR(MAX);
DECLARE #ParmDefinition NVARCHAR(MAX);
DECLARE #retIndex INT = 0;
SELECT #sqlstatement = 'SELECT #retIndexOUT=column1 #retTextOUT=column2 FROM XXX WHERE bla bla';
SET #ParmDefinition = N'#retIndexOUT INT OUTPUT, #retTextOUT NVARCHAR(MAX) OUTPUT';
exec sp_executesql #sqlstatement, #ParmDefinition, #retIndexOUT=#retIndex OUTPUT, #retTextOUT=#retText OUTPUT;
returned values are in #retIndex and #retText
Declare #variable int
Exec #variable = proc_name
DECLARE #ValueTable TABLE
(
Value VARCHAR (100)
)
SELECT #sql = N'SELECT SRS_SizeSetDetails.'+#COLUMN_NAME+' FROM SRS_SizeSetDetails WHERE FSizeID = '''+#FSizeID+''' AND SRS_SizeSetID = '''+#SRS_SizeSetID+'''';
INSERT INTO #ValueTable
EXEC sp_executesql #sql;
SET #Value='';
SET #Value = (SELECT TOP 1 Value FROM #ValueTable)
DELETE FROM #ValueTable
This worked for me:
DECLARE #SQL NVARCHAR(4000)
DECLARE #tbl Table (
Id int,
Account varchar(50),
Amount int
)
-- Lots of code to Create my dynamic sql statement
insert into #tbl EXEC sp_executesql #SQL
select * from #tbl
Here's something you can try
DECLARE #SqlStatement NVARCHAR(MAX) = ''
,#result XML
,#DatabaseName VARCHAR(100)
,#SchemaName VARCHAR(10)
,#ObjectName VARCHAR(200);
SELECT #DatabaseName = 'some database'
,#SchemaName = 'some schema'
,#ObjectName = 'some object (Table/View)'
SET #SqlStatement = '
SELECT #result = CONVERT(XML,
STUFF( ( SELECT *
FROM
(
SELECT TOP(100)
*
FROM ' + QUOTENAME(#DatabaseName) +'.'+ QUOTENAME(#SchemaName) +'.' + QUOTENAME(#ObjectName) + '
) AS A1
FOR XML PATH(''row''), ELEMENTS, ROOT(''recordset'')
), 1, 0, '''')
)
';
EXEC sp_executesql #SqlStatement,N'#result XML OUTPUT', #result = #result OUTPUT;
SELECT DISTINCT
QUOTENAME(r.value('fn:local-name(.)', 'VARCHAR(200)')) AS ColumnName
FROM #result.nodes('//recordset/*/*') AS records(r)
ORDER BY ColumnName
This was a long time ago, so not sure if this is still needed, but you could use ##ROWCOUNT variable to see how many rows were affected with the previous sql statement.
This is helpful when for example you construct a dynamic Update statement and run it with exec. ##ROWCOUNT would show how many rows were updated.
Here is the definition

I want to use dynamic variable that is declared within dynamic 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

Converting dynamic sql query's COUNT result to INT

I am trying to search within the values (table names) returned from a query to check if there is a record and some values in that record are null. If they are, then I want to insert the table's name to a temporary table. I get an error:
Conversion failed when converting the varchar value 'count(*)
FROM step_inusd_20130618 WHERE jobDateClosed IS NULL' to data type int.
This is the query:
DECLARE #table_name VARCHAR(150)
DECLARE #sql VARCHAR(1000)
DECLARE #test int
SELECT #table_name = tableName FROM #temp WHERE id = #count
SET #sql = 'SELECT * FROM ' + #table_name + ' WHERE jobDateClosed IS NULL'
--ERROR is below:
select #test = 'count(*) FROM ' + #table_name + ' WHERE jobDateClosed IS NULL'
--PRINT #sql
-- EXEC(#sql)
IF #test > 0
BEGIN
INSERT INTO #temp2 (tablename) VALUES ( #table_name);
END
SET #count = #count + 1
Any ideas how to convert the result of the count into an integer?
Check for sp_executesql where you may define output parameters.
DECLARE #table_name VARCHAR(150)
DECLARE #sql VARCHAR(1000)
DECLARE #test int
SELECT #table_name = tableName FROM #temp WHERE id = #count
DECLARE #SQLString nvarchar(500);
DECLARE #ParmDefinition nvarchar(500);
SET #SQLString = N'SELECT #test = count(*) FROM ' + #table_name + ' WHERE jobDateClosed IS NULL'
SET #ParmDefinition = N'#test int OUTPUT';
EXECUTE sp_executesql #SQLString, #ParmDefinition, #test=#test OUTPUT;
IF #test > 0
BEGIN
INSERT INTO #temp2 (tablename) VALUES ( #table_name);
END
SET #count = #count + 1
Shouldn't be "SET" instead of "select" ?
E.g., changing:
select #test = 'count(*) FROM ' + #table_name + ' WHERE jobDateClosed IS NULL'
for:
SET #test = 'select count(*) FROM ' + #table_name + ' WHERE jobDateClosed IS NULL'
As I see, your problem is, that $test variable is INT and you are trying to assign to it the TEXT value 'count ...'
Use aproach like:
SELECT somevalue INTO myvar FROM mytable WHERE uid=1;
I trimmed out the stuff not needed to show how to do this, so here it is:
DECLARE #table_name VARCHAR(150)
DECLARE #CountStatement NVARCHAR(1000)
DECLARE #test int
SELECT #table_name = tableName FROM #temp WHERE id = #count
SET #CountStatement = 'select #test = count(*) FROM ' + #table_name + ' WHERE jobDateClosed IS NULL'
EXECUTE sp_executesql #CountStatement, N'#test INT OUTPUT', #test OUTPUT;
SELECT #test

Adding two dynamic variable and store it in INT type column

I've two dynamic variable ...
declare #count nvarchar(max)
declare #totalCount int
set #count = ' ( SELECT COUNT(*) FROM '+ #Table +' where [Name] = '''+ CAST(#Name as nvarchar(max)) +''' ) '
set #totalCount = CAST(CAST(#count as nvarchar(max)) + CAST(#Qty as nvarchar(max)) as INT);
I'm getting an error
conversion failed when converting the nvarchar value to datatype int....
then I need to store #totalCount in [TotalCount] column of type INT ...PLease help
he variable table name requires using dynamic SQL. The example below assigns the computed value to the #totalCount variable using a parameterized query output parameter.
DECLARE
#totalCount int
, #Qty int = 5
, #Sql nvarchar(MAX)
, #Table sysname = 'Table'
, #Name nvarchar(MAX) = N'Name';
SET #Sql = N'SELECT #totalCount = COUNT(*) + #Qty
FROM ' + QUOTENAME(#Table) + ' where [Name] = #Name;';
EXEC sp_executesql
#Sql
, N'#Name nvarchar(MAX), #Qty int, #totalCount int OUTPUT'
, #Name = #Name
, #Qty = #Qty
, #totalCount = #totalCount OUT;

SQL Statement as parameters

Is it possible to do something like that in SQL?
DECLARE #t Nvarchar(50)
SET #t = 'SELECT * FROM KIN_PHON'
execute #t --??
Use exec:
DECLARE #t Nvarchar(50)
SET #t = 'SELECT * FROM KIN_PHON'
exec (#t)
Or with parameters, sp_executesql:
declare #sql nvarchar(max)
set #sql = 'select * from YourTable where ID = #ID'
execute sp_executesql #sql, N'#ID int', #ID = 42;