How to store results of dynamic SQL into a variable - sql

is there a way to store the results of an exec statement in a varchar?
DECLARE #TableName varchar(100)
DECLARE #ExecStatement varchar(max)
DECLARE #PromotionXML varchar(max)
SET #TableName = 'Feeds'
Set #ExecStatement = (
'
SET #PromotionXML = (
SELECT
*
FROM
' + #TableName + ' for xml auto, elements
)'
)
exec #ExecStatement
select #PromotionXML

You need to use sp_executesql, not EXEC, since you need to treat the inner variable as an output parameter (which you can't do with EXEC). Also all of these parameters should be NVARCHAR, not VARCHAR (though I'm curious why you aren't returning the xml as XML).
DECLARE
#TableName NVARCHAR(512),
#sql NVARCHAR(MAX),
#xml NVARCHAR(MAX);
SET #TableName = N'dbo.Feeds';
SET #sql = N'SELECT #xml = CONVERT(NVARCHAR(MAX), (
SELECT * FROM ' + #TableName + ' FOR XML AUTO, ELEMENTS));';
EXEC sp_executesql #sql, N'#xml NVARCHAR(MAX) OUTPUT', #xml OUTPUT;
SELECT #xml;

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.

Convert column values into string

I'm trying to write e proc which will convert column values into a string separated with a character: ',' for example.
it stucks on this line exec #maxcount = sp_executesql #temp and returns the value of #maxxount any suggestions how could I set a value of dynamic query execution so that it continued processing all the function an executed the correct answer.
ALTER procedure [dbo].[usp_stringConvert](
#table_name varchar(101),
#column_name varchar(100),
#separator varchar(20)
)
as
declare #maxcount int, #temp nvarchar(1000)
declare #count int
declare #result varchar(1000)
set #result =''
set #count =1
set #temp= Concat('select count(', #column_Name ,') from ', #table_name)
exec #maxcount = sp_executesql #temp
while (#count<#maxcount)
begin
if #count!=1
set #result+=#separator
set #temp=Concat('select ' , #column_name ,' from ' , #table_name , 'where #count = row_number() over(order by (select (100)))')
exec #temp = sp_executesql #temp
set #result =CONCAT(#result, #temp)
set #count+=1;
end
select #result;
Using regular SQL in SQL Server, you can concatenate strings using:
select stuff( (select concat(separator, column_name)
from table_name
for xml path ('', type)
).value('.', nvarchar(max)
), 1, len(separator), ''
)
You should be able to turn this into dynamic SQL using:
declare #sql nvarchar(max);
declare #result nvarchar(max);
set #sql = N'
select #result = stuff( (select concat(#separator + [column_name]
from [table_name]
for xml path ('''', type)
).value(''.'', nvarchar(max)
), 1, len(#separator), ''
)
';
set #sql = replace(#sql, '[table_name]', quotename(#table_name));
set #sql = replace(#sql, '[column_name]', quotename(#column_name));
exec sp_executesql #sql,
N'#result nvarchar(max) output',
#result=#result output;
select #result;

T-SQL Create Table with Dynamically Named Database with sp_executesql

I am attempting to create a table in T-SQL using sp_executesql. The name of the database containing the table is dynamic.
DECLARE #ID int = 1031460
DECLARE #TableName nvarchar(max) = '[MyDatabase' + CAST(#ID as nvarchar(10)) + '].[dbo].[MyTable]'
DECLARE #CreateTable nvarchar(max) = N''
SELECT #CreateTable =
N'
CREATE TABLE #TableName
(
ID int
)
'
EXECUTE sp_executeSQL #CreateTable, N'#TableName nvarchar(max)', #TableName = #TableName
This script results in this error:
Msg 102, Level 15, State 1, Line 2
Incorrect syntax near '#TableName'.
What is the best way to specify the name of the table to create dynamically based on parameters of sp_executeSQL?
You cannot pass Tablename as a parameter even we using sp_executesql procedure. You have to build you own dynamic sql query
SELECT #CreateTable =
N'
CREATE TABLE ' + #TableName + '
(
ID int
)
'
Exec sp_executesql #CreateTable
When you are passing the table name as a parameter to sp_executesql, it treats it as a literal string, to make it treat it as an object name try something like this......
DECLARE #ID int = 1031460
DECLARE #TableName nvarchar(max) = QUOTENAME('MyDatabase' + CAST(#ID as nvarchar(10)))
+ '.[dbo].[MyTable]'
DECLARE #CreateTable nvarchar(max);
SET #CreateTable = N' CREATE TABLE ' + #TableName
+ N' (
ID int
)'
Exec sp_executesql #CreateTable
EDIT
It is good practice to check if an object already exists before you try to create it.
You can check if the object already exists and drop it and then create the new one, you code should look something like.....
DECLARE #ID int = 1031460
DECLARE #TableName nvarchar(max) = QUOTENAME('MyDatabase' + CAST(#ID as nvarchar(10)))
+ '.[dbo].[MyTable]'
DECLARE #CreateTable nvarchar(max), #DropTable nvarchar(max);
-- Drop table if already exists
SET #DropTable = N' IF OBJECT_ID('''+ #TableName +''') IS NOT NULL '
+ N' DROP TABLE ' + #TableName
Exec sp_executesql #DropTable
SET #CreateTable = N' CREATE TABLE ' + #TableName
+ N' (
ID int
)'
Exec sp_executesql #CreateTable

SQL add a variable to a query

How do I create variables that are specified once and then used in queries later in a script? These variables may be used multiple times in a query, and in multiple queries in a script. I use #x as such a variable in the examples below.
What I want to do is something like:
Declare #Query nvarchar(1000)
Declare #x nvarchar(40)
Set #x = 'test'
Set #Query = 'Select [Name]
, ' + #x + ' as [TestCase]
From mytable'
Exec (#Query)
-- returns "Invalid column name 'test'"
Which returns the error mentioned above. I would like it to achieve the equivalent of:
Declare #Query nvarchar(1000)
Declare #x nvarchar(40)
Set #x = 'test'
Set #Query = 'Select [Name]
, ''test'' as [TestCase]
From mytable'
Exec (#Query)
-- Returns e.g.
-- Name TestCase
-- Alice Test
-- Bob Test
I also note that the following doesn't work and returns the same error as the first:
Declare #Query nvarchar(1000)
Declare #x nvarchar(40)
Set #x = 'test'
Set #Query = 'Select [Name]
, ' + 'test' + ' as [TestCase]
From mytable'
Exec (#Query)
-- returns "Invalid column name 'test'"
Based on the error and since I'm not trying to use the #x as a column name, but just as a variable, I assume I'm using an invalid implementation of a variable.
Since you're not trying to use a variable as a column name, you do not need to use dynamic SQL at all. (Which is a Good Thing(TM) since dynamic SQL should only be used with a great deal of caution due to it being a great attack surface.)
A simple:
declare #x nvarchar(40)
set #x = 'test'
select [Name], #x as TestCase
from mytable
will do.
That being said, if you have a use case for dynamic SQL (again the particular query in question here does not but perhaps an ad-hoc query is being passed in to the procedure), the thing to do would be to pass your variable as a parameter to the query via sp_executesql. This is akin to creating a stored procedure with parameters:
declare #x nvarchar(40)
declare #query nvarchar(1000)
set #x = 'test'
set #query = 'select [Name], #x as TestCase from mytable'
exec sp_executesql #query, N'#x nvarchar(1000)', #x
You were missing quotes. Thats it. Try below code.
Declare #Query nvarchar(1000)
Declare #x nvarchar(40)
Set #x = 'test'
Set #Query = 'Select [Name]
, ''' + #x + ''' as [TestCase]
From mytable'
Exec (#Query)
Declare #Query nvarchar(1000)
Declare #x nvarchar(40)
Set #x = 'test'
Set #Query = 'Select [Name],'++''''+#x+''''+ ' as [TestCase]
From mytable'
print #query
Output:
Select [Name],'test' as [TestCase]
From mytable

How to pass variable/parameter as a datatype?

I would like to be able to change my datatypes and other values as a variable or as a parameter so that it could be changed and passed easily.
declare #datatype nvarchar(20) = 'datetime'
declare #inputvalue nvarchar(20) = '2015-10-21'
declare #variable #datatype = #inputvalue
exec spStoredProcedure #StoredProcedureParam = #variable
You would need to use dynamic sql inside your stored procedure for it, something like ....
declare #datatype nvarchar(20) = 'datetime'
declare #inputvalue nvarchar(20) = '2015-10-21'
-- Inside your proc you would do something like.....
Declare #Sql NVARCHAR(MAX);
SET #Sql = N' Declare #variable '+ QUOTENAME(#datatype) + N' = #inputvalue '
+ N' Select #variable AS VariableValue'
Exec sp_executesql #Sql
,N'#inputvalue nvarchar(20)'
,#inputvalue