SQL Server Select variable into another variable - sql

I build a sql query as:
declare #query1 varchar(1000)
declare #results varchar(4000)
set #results = ''
WHILE (condition)
BEGIN
set #query1 = 'SELECT column FROM table'
set #results = #results + ", " + (select #query1)
END
print #results
So, for example after 2 iterations, I would like to have:
columnvalue, columnvalue
However, in the above code, #results holds the actual sql query instead.

You never execute query1, but istead assign it the text-string SELECT COLUMN FROM table.
What you're looking for is something like SELECT #query1 = column from table

OK. this is how it's done:
declare #query1 nvarchar(1000)
declare #results nvarchar(4000)
set #results = ''
declare #changesOUT nvarchar(1000)
set #query1 = 'SELECT #changes = column FROM table WHERE condition'
EXEC sp_executesql #query1, N'#changes varchar(4000) OUTPUT', #changes=#changesOUT OUTPUT
set #results = #results + (SELECT #changesOUT) + char(10)
print #results

declare #query1 varchar(1000)
declare #results varchar(4000)
set #results = ''
IF OBJECT_ID('tempdb..#ResultSet') IS NOT NULL
BEGIN
DROP TABLE #ResultSet;
END
CREATE TABLE #ResultSet (mycolumn VARCHAR(1000))
WHILE (condition)
BEGIN
set #query1 = 'SELECT column FROM table'
INSERT INTO #ResultSet // Temp table to store result of running dynamic query
exec (#query1) // Exec to run dynamic query
SELECT #query1 = mycolumn FROM #ResultSet
set #results = #results + ', ' + (select #query1)
END
print #results
drop table #ResultSet
Hope this helps.

Related

Dynamically Creating a table and inserting Rows inside a SP

I am trying to run a Stored Procedure that Inserts into a Table.
I keep getting the Incorrect syntax near 'tbl_1_2'.
It doesn't Insert the data.I am using MSSQL2012
Alter PROCEDURE [dbo].[TT] AS
BEGIN
declare #tbl varchar(100);
set #tbl='tbl_1_2';
declare #sql varchar(100);
DECLARE #ptablename VARCHAR(max) = (#tbl)
set #ptablename=#tbl
SET #sql = 'INSERT INTO ' + #ptablename ;
EXEC (#sql)
select *
from (
values('1','2')
) t1 (c1, c2)
End
See this sample and compare with your code to understand your error.
Create Table Test (ID int, Name sysname)
Go
Declare #TableName sysname = 'Test'
DECLARE #ID int = 1
DECLARE #Name sysname = 'Meysam'
Declare #SQL nVarchar(4000) = 'INSERT #TableName (ID, Name) Values (#ID, N''#Name'')'
Set #SQL = REPLACE(#SQL, '#TableName', #TableName)
Set #SQL = REPLACE(#SQL, '#ID', #ID)
Set #SQL = REPLACE(#SQL, '#Name', #Name)
EXEC (#SQL)
SELECT * FROM Test

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

T sql - How to store results from a dynamic query using EXEC or EXECUTE sp_executesql

I am trying to write a dynamic query. Let's say i have a table like below, which represents the hierarchy level of a sales agent:
AgentNumber Level1Agent Level2Agent Level3Agent Level4Agent Level5Agent
1122334455 1122334499 1122334488 1122334477 1122334466 1122334455
I want to be able to dynamically select a level based on a specified agent. My EXECUTE statement seems to work correctly, but how do I get the result stored in a variable I can use later? Every answer I have found seems to only get me a success return variable, not the actual query result.
Below is my code:
DECLARE #level INT = 1;
DECLARE #agent CHAR(10) = 1122334455;
DECLARE #colname NVARCHAR(11) = CONCAT('Level',#level,'Agent');
DECLARE #whereclause NVARCHAR(35) = CONCAT('WHERE AgentNumber = ',#agent);
DECLARE #qry NVARCHAR(300) = 'SELECT ' + #colname + ' FROM dbo.TABLE ' + #whereclause;
DECLARE #up NVARCHAR(10);
EXECUTE sp_executesql #qry, #up OUT
SELECT #up
The output of #up is NULL. If I change the last two lines to:
EXECUTE #up = sp_executesql #qry
SELECT #up
Now the output of #up is 0.
I want the output of 1122334499 and I need it stored in a variable that can later be used and inserted into a table.
Here is a fully functional example of how you can do this. Notice this is using a parameterized where clause and quotename around the column name in the dynamic sql to prevent sql injection.
if OBJECT_ID('tempdb..#Agents') is not null
drop table #Agents
create table #Agents
(
AgentNumber char(10)
, Level1Agent char(10)
, Level2Agent char(10)
, Level3Agent char(10)
, Level4Agent char(10)
, Level5Agent char(10)
)
insert #Agents
select '1122334455', '1122334499', '1122334488', '1122334477', '1122334466', '1122334455'
DECLARE #level INT = 3;
DECLARE #agent CHAR(10) = 1122334455;
DECLARE #colname NVARCHAR(11) = CONCAT('Level',#level,'Agent');
declare #agentout char(10)
DECLARE #qry NVARCHAR(300) = 'SELECT #agent_out = ' + quotename(#colname) + ' FROM #Agents WHERE AgentNumber = #agentin';
EXECUTE sp_executesql #qry, N'#agentin char(10), #agent_out char(10) output', #agentin = #agent, #agent_out = #agentout output
select #agentout
You can try this :
DECLARE #level INT = 1;
DECLARE #agent CHAR(10) = 1122334455;
DECLARE #colname NVARCHAR(11) = CONCAT('Level',#level,'Agent');
DECLARE #whereclause NVARCHAR(35) = CONCAT('WHERE AgentNumber = ',#agent);
DECLARE #qry NVARCHAR(300) = 'SELECT #agentout=' + #colname + ' FROM dbo.TABLE ' + #whereclause;
DECLARE #up NVARCHAR(10);
EXECUTE sp_executesql #qry, N'#agentout NVARCHAR(10) OUTPUT', #agentout=#up OUTPUT
SELECT #up
Create a variable table and makes your query insert the results you want there. Something like this:
declare #results table(field1 varchar(max), field2 varchar(max));
declare #sqlStatement varchar(max);
set #sqlStatement = 'insert into #results(field1, field2) select field1, field2 from table';
EXECUTE #sqlStatement;
select * from #results; --It will print the results from your sql statement!

Values not passed to dynamic query in sql server

Is it possible to print the Dynamic select statement after passing the parameters values.When i print the SELECT #SQL.It is giving only select statement without parameter values.In my below procedure the dynamic select statement not giving correct output after passing the parameters.But when i directly passing the the parameter values into the select statement it is giving correct output.In my below procedure splitting function is working fine.Else part in
if statement is not working properly.
CREATE TYPE TableVariable AS TABLE
(
id int identity(1,1),
field_ids INT,
value VARCHAR(MAX)
)
Alter PROCEDURE Testing
(
#TableVar TableVariable READONLY,
#Catalog_id INT
)
AS
Declare #maxPK INT
Declare #pk INT
Declare #fid INT
Declare #is_List SMALLINT
Declare #val VARCHAR(MAX)
Declare #field_Type VARCHAR(50)
Declare #Where VARCHAR(MAX)
Declare #SQL NVARCHAR(MAX);
Set #pk = 1
BEGIN
BEGIN TRY
SET NOCOUNT ON;
Select #maxPK = count(*) From #TableVar
SELECT #Catalog_id
Set #SQL = 'SELECT DISTINCT v1.entity_id from values v1 inner join listings l ON v1.entity_id = l.entity_id WHERE l.c_id=#Catalog_id'
While #pk <= #maxPK
BEGIN
SELECT #fid= field_ids FROM #TableVar where id=#pk;
SELECT #val= value FROM #TableVar where id=#pk;
SELECT #field_Type=type,#is_List=is_list FROM FIELD WHERE ID=#fid
IF (#is_List = 0)
BEGIN
SET #SQL += ' and exists (select 1 from values v'+convert(varchar(15),#pk+1)+' where v1.entity_id = v'+convert(varchar(15),#pk+1)+'.entity_id and v'+convert(varchar(15),#pk+1)+'.field_id=#fid and(value IN(SELECT val FROM spliting(#val,'',''))))'
SELECT #fid
END
else IF (#is_List = 1 OR #field_Type = 'xy')
BEGIN
SET #SQL += ' and exists (select 1 from values v'+convert(varchar(15),#pk+1)+' where v1.entity_id = v'+convert(varchar(15),#pk+1)+'.entity_id and v'+convert(varchar(15),#pk+1)+'.field_id=#fid and(value in(#val)))'
SELECT #fid
END
Select #pk = #pk + 1
END
EXECUTE SP_EXECUTESQL #SQL, N'#Catalog_id int,#fid int,#val varchar(max)',#Catalog_id=#Catalog_id,#fid=#fid,#val=#val
SELECT #SQL
END TRY
BEGIN CATCH
END CATCH
END
DECLARE #DepartmentTVP AS TableVariable;
insert into #DepartmentTVP values(1780,'Smooth As Silk Deep Moisture Shampoo,Smooth As Silk Deeper Moisture Conditioner')
--insert into #DepartmentTVP values(1780,'Smooth As Silk Deeper Moisture Conditioner')
insert into #DepartmentTVP values(1782,'037-05-1129')
insert into #DepartmentTVP values(2320,'["fairtrade","usda_organic","non_gmo_verified"]')
SELECT * FROM #DepartmentTVP
EXEC Testing #DepartmentTVP,583
Yes right before the statment:
EXECUTE SP_EXECUTESQL #SQL, N'#Catalog_id int,#fid int,#val varchar(max)',#Catalog_id=#Catalog_id,#fid=#fid,#val=#val
type:
print #SQL

Can I use variable in condition statement as value with where condition that test that value

I have the following stored procedure:
ALTER proc [dbo].[insertperoll] #name nvarchar(50) , #snum int , #gnum int
as
DECLARE #value nvarchar(10)
SET #value = 's'+CONVERT(nvarchar(50),#snum)
DECLARE #sqlText nvarchar(1000);
DECLARE #sqlText2 nvarchar(1000);
DECLARE #sqlText3 nvarchar(1000);
declare #g nvarchar(50) = '''g1'''
SET #sqlText = N'SELECT ' + #value + N' FROM dbo.GrideBtable'
SET #sqlText2 = ' where Gnumber = '+#g --here is the problem it error invalid column name -- the #g is value from the table condition
set #sqlText3 = #sqlText+#sqlText2
Exec (#sqlText3) -- here how can i save the result of the exec into varibale
declare #sal nvarchar(50) = #sqlText3
insert employ (name,Snumber,Gnumber,Salary) values(#name,#snum,#gnum,#sal)
QUESTION: How to put in condition variable gets value from the table when i exec it it think that the #g is column but its not its a value from the table to test it so i display one value after the exec the other QUESTION is how to save the result from the exec in variable and then use that value
I'm using SQL Server 2008 (9.0 RTM)
This will be a stored procedure
Thanks in advance
Not sure why you would go through all the loops to insert into the table where you can have a simple insert query like ..
ALTER PROC dbo.[insertperoll] #name nvarchar(50) , #snum int , #gnum int
AS
insert employ (name, Snumber, Gnumber, Salary)
select #name
, #sum
, #gnum
, case when #snum = 1 then s1
when #snum = 2 then s2
when #snum = 3 then s3
when #snum = 4 then s4
end as Salary
from dbo.GrideBtable
where Gnumber = #gnum
If your intent is to have the proc retrieve a salary value from a column determined from the parameter snum and then make an insert into employ using the values passed as parameters and the salary retrieved I think you could refactor your procedure to this:
CREATE proc [dbo].[insertperoll] #name nvarchar(50) , #snum int , #gnum int AS
DECLARE #g NVARCHAR(50) = 'g1'
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'INSERT employ (name,Snumber,Gnumber,Salary) '
SET #sql += N'SELECT ' + QUOTENAME(#name, '''')
SET #sql += N', ' + CAST(#snum AS NVARCHAR(50))
SET #sql += N', ' + CAST(#gnum AS NVARCHAR(50))
SET #sql += N', s' + CAST(#snum AS NVARCHAR(50))
SET #sql += N' FROM dbo.GrideBtable'
SET #sql += N' WHERE Gnumber = ' + QUOTENAME(#g, '''')
EXEC (#sql)
Of course you could add the #g variable to the procedure parameters instead of having it hard coded in the procedure and call it as:
EXEC insertperoll #name='john', #snum=10, #gnum=100, #g='g1'
Sample SQL Fiddle (with some assumptions made about table structure)
You could do this using sp_executesql instead of exec() since this will allow you to use parameters, you can use an output parameter to get the value from the query:
DECLARE #SQL NVARCHAR(MAX) = N'SELECT #val = ' + CONVERT(NVARCHAR(10),#snum) +
N' FROM dbo.GrideBtable WHERE Gnumber = #G1';
DECLARE #val INT; -- NOT SURE OF DATATYPE REQUIRED
EXECUTE sp_executesql #SQL, N'#G1 VARCHAR(20), #val INT OUT', 'G1', #val OUT;