Getting output in a variable from dynamic SQL - sql

I am using a dynamic sql i.e.
DECLARE #searchstring VARCHAR(500)
DECLARE #str VARCHAR(MAX)
SELECT #str = 'SELECT * FROM Table1 WHERE ' + #searchstring
EXECUTE #str
What I need is I want to select one column value from above dynamic sql to pass in a different SP
Let's say I need ID column value and pass it to another sp named GetAnotherData #Ids. How can I do that?

well you can go with Alexander Fedorenko example, but if you don't want to create any temp tables, you can use output xml parameter to pass your ids:
declare #stmt nvarchar(max), #Data xml, #searchstring nvarchar(max)
select #stmt = '
select #Data = (
select id
from Table1
where ' + #searchstring + '
for xml raw(''Data'')
)
'
exec sp_executesql
#stmt = #stmt,
#params = N'#Data xml output',
#Data = #Data output
select
T.C.value('#id', 'int') as id
from #Data.nodes('Data') as T(C)
sql fiddle demo

The following example creates a user-defined table type that has one Id column. Further the INSERT #RetIds EXEC(#STR) statement fills the parameter list, and then passes the values to a stored procedure
CREATE TYPE RetIds AS TABLE
(
Id int
)
DECLARE #searchstring varchar(500) = 'AND SearchCol = 1'
DECLARE #str varchar(max)
SELECT #str ='SELECT Id FROM dbo.test6 WHERE 1 = 1 ' + #searchstring
DECLARE #RetIds AS RetIds
INSERT #RetIds
EXEC(#str)
EXEC dbo.ExecIds #RetIds
See demo on SQLFiddle

Related

Passing a variable out of a SQL query

Is it possible to pass a variable out of a SQL query?
I am building up the initial query using a variable. I have added a simplified subset of my query below.
Thanks
declare #query Nvarchar(max)
declare #ColumnName Nvarchar(max)
set #ColumnName = 'MyColumn'
SET #query = 'Select ' + #ColumnName + ' from [MyTable] WHERE [MyCondition]'
EXECUTE sp_executesql #query
Can I return this result as a variable to pass to another query?
Yes. You use an output parameter:
declare #query Nvarchar(max);
declare #ColumnName Nvarchar(max);
declare #outval <type>; -- whatever type
set #ColumnName = 'MyColumn'
set #query = 'Select #outval =' + #ColumnName + ' from [MyTable] where [MyCondition]';
execut sp_executesql #query,
N'#outval <type> output',
#outval = #outval output;
Store the results in table variable and then convert it into XML.
Declare #xml XML
declare #query Nvarchar(max)
declare #ColumnName Nvarchar(max)
set #ColumnName = 'MyColumn'
declare #Table as TABLE(
MyColumn varchar(Max)-- Your Column datatype
)
SET #query = 'Select ' + #ColumnName + ' from [MyTable] WHERE [MyCondition]'
INSERT INTO #Table
EXECUTE sp_executesql #query
select #xml=MyColumn from #Table for XML PATH('')
How you want to pass returned result to other query?
What i can think of create a function return a table and call that function on other query:
CREATE FUNCTION test (#id int)
RETURNS #testTable TABLE(id int)
AS
begin
insert into #testTable select id from #your_table where id = #id
return
end
This will return a table you can check using :
select * from test(2); --will give you a table
If you want to use in a query:
`select * from #second_table where id in (select * from test2(#id parameter))` --- will filter query by id returned by function.

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!

How to store a dynamic SQL result in a variable in T-SQL?

I have a stored procedure which takes 'table name' as parameter. I want to store my 'exec' results to a variable and display using that variable.
Here is my T-SQL stored procedure..
create procedure DisplayTable( #tab varchar(30))
as
begin
Declare #Query VARCHAR(30)
set #Query='select * from ' +#tab
EXEC (#Query)
END
I want to do something like this..
SET #QueryResult = EXEC (#Query)
select #QueryResult
How do i achieve this.. Please help.. I am a beginner..
You can use XML for that. Just add e.g. "FOR XML AUTO" at the end of your SELECT. It's not tabular format, but at least it fulfills your requirement, and allows you to query and even update the result. XML support in SQL Server is very strong, just make yourself acquainted with the topic. You can start here: http://technet.microsoft.com/en-us/library/ms178107.aspx
alter procedure DisplayTable(
#tab varchar(30)
,#query varchar(max) output
)
as
BEGIN
Declare #execution varchar(max) = 'select * from ' +#tab
declare #tempStructure as table (
pk_id int identity
,ColumnName varchar(max)
,ColumnDataType varchar(max)
)
insert into
#tempStructure
select
COLUMN_NAME
,DATA_TYPE
from
INFORMATION_SCHEMA.columns
where TABLE_NAME= #tab
EXEC(#execution)
declare #ColumnCount int = (SELECT count(*) from #tempStructure)
declare #counter int = 1
while #counter <= #ColumnCount
BEGIN
IF #counter = 1
BEGIN
set #query = (SELECT ColumnName + ' ' + ColumnDataType FROM #tempStructure where pk_id= #counter)
END
IF #counter <> 1
BEGIN
set #query = #query + (SELECT ',' + ColumnName + ' ' + ColumnDataType FROM #tempStructure where #counter = pk_id)
END
set #counter = #counter + 1
END
END
When you execute the SP, you'll now get a return of the structure of the table you want.
This should hopefully get you moving.
If you want the table CONTENTS included, create yourself a loop for the entries, and append them to the #query parameter.
Remember to delimit the #query, else when you read it later on, you will not be able to restructure your table.
First of all you have to understand that you can't just store the value of a SELECTon a table in simple variable. It has to be TABLE variable which can store the value of a SELECTquery.
Try the below:
select 'name1' name, 12 age
into MyTable
union select 'name2', 15 union
select 'name3', 19
--declaring the table variable and selecting out of it..
declare #QueryResult table(name varchar(30), age int)
insert #QueryResult exec DisplayTable 'MyTable'
select * from #QueryResult
Hope this helps!

SELECT Query with Columns stored in a variable

I have a stored procedure in which I am getting table's column which is needed for SELECT statement in a variable with comma separated. But It is not working for me.:
SP:
ALTER PROCEDURE [dbo].[SPGet_Assistance_Detail]
(
#Id int,
#UserDesig varchar(20) --User Desig can be 'FFR' or 'HO'
)
AS
DECLARE #Cols VARCHAR(MAX)
SELECT #Cols = Column_Listing FROM Role_Col_Mapping WHERE Tbl_Name = 'Assistance' and Role = #UserDesig
SELECT #Cols FROM dbo.Assistance WHERE Service_Id=(#Id)
RETURN
Here Role_Col_Mapping has fields like: Tbl_Name, Role , and Column_Listing. It stores data of cols allowed to any user based on his role in any table. And Assistance is a table which columns' data I needed to display.
I am getting wrong output. Which is cols separated by comma.
You must use dynamic SQL - something like this:
ALTER PROCEDURE [dbo].[SPGet_Assistance_Detail]
(
#Id int,
#UserDesig varchar(20) --User Desig can be 'FFR' or 'HO'
)
AS
DECLARE #Cols VARCHAR(MAX)
SELECT #Cols = Column_Listing FROM Role_Col_Mapping WHERE Tbl_Name = 'Assistance' and Role = #UserDesig
DECLARE #query NVARCHAR(MAX)
SELECT #query = 'SELECT ' + #Cols + ' FROM CRM.dbo.Assistance WHERE Service_Id=' + cast(#Id AS VARCHAR(MAX))
EXEC sp_executesql #query
RETURN

Dynamically Create Update SQL In Stored Procedure

I try to create a stored procedure to update a table record whose sql statement is dynamically created. I wrote some codes but am stoped in to run this query dynamically, How can i run this query or is there a better solution for this problem.
How this SP work?=> I send the columns names,values and datatype of the record that need update to SP like below
<e columnName=''PaymentStatus'' value=''99'' type=''nvarchar''/>
<e columnName=''HotelProvider'' value=''GAT2'' type=''nvarchar''/>
Then travel the nodes and create an Update statement, but can't execute it :))
I am giving a part of SP to understand the question better.
DECLARE #UpdateXml xml = '
<xml>
<e columnName=''PaymentStatus'' value=''99'' type=''nvarchar''/>
<e columnName=''HotelProvider'' value=''GAT2'' type=''nvarchar''/>
</xml>';
DROP TABLE ##UpdateFields
SELECT
t.c.value('#columnName', 'varchar(max)') AS ColumnName,
t.c.value('#value', 'varchar(max)') AS Value,
t.c.value('#property', 'varchar(max)') AS PropertyOf,
t.c.value('#type', 'varchar(max)') AS ColumnType
INTO ##UpdateFields
from #UpdateXml.nodes('/xml/e') as t(c)
DECLARE #SQL nvarchar(MAX) = 'UPDATE HotelBooking ';
DECLARE #SQLUpdatePart nvarchar(MAX);
SET #SQLUpdatePart = 'SET ';
SELECT #SQLUpdatePart= #SQLUpdatePart+ColumnName +'='+'#QP_'+ColumnName+',' FROM ##UpdateFields WHERE PropertyOf IS NULL;
DECLARE #SQLWherePart nvarchar(MAX);
SET #SQLWherePart = ' WHERE Id=2';
DECLARE #ParmDefinition nvarchar(MAX)='';
SELECT #ParmDefinition = #ParmDefinition+'#QP_'+ColumnName+' '+ColumnType+',' FROM ##UpdateFields;
SELECT #ParmDefinition
SELECT #SQL + #SQLUpdatePart + #SQLWHerePart;
Last two select statements results are:
#QP_PaymentStatus nvarchar,#QP_HotelProvider nvarchar,#QP_TransactionId uniqueidentifier,#QP_UpdatedDate datetime
and
UPDATE HotelBooking SET PaymentStatus=#QP_PaymentStatus,HotelProvider=#QP_HotelProvider,UpdatedDate=#QP_UpdatedDate,TransactionId=#QP_TransactionId WHERE Id=2
Now How can I give the #QP parameters to sp_executesql() method dynamically?
You can do it by wrapping sp_executesql call in another exec:
declare #updateStr nvarchar(1000)
-- #updateStr = N'select * from ATable where ID = #p1'
set #updateStr = N'N''select * from ATable where ID = #p1'''
declare #paramStr nvarchar(100)
-- #paramStr = N'#p1 int'
set #paramStr = N'N''#p1 int'''
declare #actualParameters nvarchar(100)
set #actualParameters = N'#p1 = 10'
-- Concatenate parts of query into a variable
declare #sql nvarchar(max)
set #sql = N'sp_executesql ' + #updateStr + ',' + #paramStr + ', ' + #actualParameters
-- And voila!
exec (#sql)