sql server - fill results from executed query string in a temp table dynamically - sql

I'm writing a stored procedure. I have a string which contains an sql query. For example:
DECLARE #sql nvarchar(max)
SET #sql = (N'SELECT pkOrderID FROM Orders')
(Just to note: this isn't what the select statement looks like. This is just an example of what I mean) I then want to execute the string and put the result in a temporary table E.g. #tempTable. I know EXEC(#sql) exists but not sure if it will do me any good in this situation. The other twist is that I do not know the names of all the columns in the returned #sql so the temp table #tempTable needs to be created dyanmically based off the return from #sql. Thanks for any help.

I think you could use SELECT INTO to do what you want but it would mean updating your string:
DECLARE #sql nvarchar(max)
SET #sql = (N'SELECT frompkOrderID INTO #tmporders FROM Orders')
then you should be able to run EXEC #sql to create the table
more information about SELECT INTO here : http://msdn.microsoft.com/en-au/library/ms188029.aspx

There is no simple way to do this. The problem with #JanR's solution is that the #tmporders table will be out of scope to the script that calls your stored procedure (ie It will produce an error like "Invalid object name '#rtmporders'"
One alternative is to use a global temp table (eg ##tmporders).
So your SP might look like this:
CREATE PROCEDURE TestSP
AS
BEGIN
SELECT pkOrderID INTO ##tmporders FROM Orders
END
GO
And the calling script might be like:
EXEC TestSP
SELECT * FROM ##temporders

Related

query inside the variable

Is it possible in SQL to use a variable to store query.
For example to save time when subquery is used multiple times inside the main query.
Example:
DECLARE #my_query as varchar(250) = select x from my_table where my_table = y.your_table
SELECT
a,b,c,(#my_query),d,e,f
FROM my_table_1
Is it possible in SQL to use a variable to store query.
Depend on your definition of "query". If you mean store the text which we use to execute the command, then the answer is YES. If you mean an object type query, then the answer is not - since there is no data type that fit this.
What I mean is that a variable can store a value which is string. The string can be any query command that you want. Therefore, you can store for example the text "select col1,col2 from table1".
Next you need to ask how can we use this text in order to execute it as part of a query, which is done using dynamic query.
We can execute a text of a query using the build-in stored procedure sp_executesql, which is build for such needs.
For example:
-- DECLARE VARIABLE
DECLARE #MyQuery NVARCHAR(MAX)
-- SET the value of the variable
SET #MyQuery = 'SELECT ''Yes I can'''
-- Executing a dynamic query
EXECUTE sp_executesql #MyQuery
Here is another example which look more close to your question:
-- First let's create a table
CREATE TABLE T(ID INT)
INSERT T(ID) VALUES (1),(2)
GO
-- And here is what you sked about:
-- DECLARE VARIABLE
DECLARE #MyQuery NVARCHAR(MAX)
-- SET the value of the variable
SET #MyQuery = 'select ID from T where ID = ''1'''
-- Let's combine the text to a full query now
DECLARE #FullQuery NVARCHAR(MAX)
SET #FullQuery = '
SELECT
ID,(' + #MyQuery + ')
FROM T
'
PRINT #FullQuery
-- Executing a dynamic query
EXECUTE sp_executesql #FullQuery
NOTE! Your specific sample of query will return error, which is not related to the question "Is it possible in SQL to use a variable to store query". This is a result of the "query" is not well formatted.
Important! It is HIGHLY recommended to read the document about this stored procedure and learn a bit more of the options it provides us.
https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-executesql-transact-sql?view=sql-server-ver15

How to dynamically create and populate a local temp table (when the table headers are unknown)?

I am currently using code similar to the following:
SET #Query = 'SELECT * INTO #Temp FROM MyTable'
EXEC sp_executesql #Query
Obviously, this does not work. Until now, I have been getting around this problem by using global temporary tables within my dynamic sql. However, this is not an option once the stored procedure is released to users, as their global temp tables would conflict with one another.
How might I get around this issue? I must specify that the structure of the table MyTable is unknown, so creating the temp table outside of the dynamic sql is (presumably?) not an option.
Edit: Apologies if I was not specific enough with exactly what I am trying to achieve - I thought it would be best to keep this question as relevent to the actual issue as possible.
Obviously, the string that I am trying to execute is not fixed. It is instead constructed so that the table, from which the data is being retrieved, may be specified. Although still not overly complex, the actual query string that I am using is more along the lines of
#Query = CONCAT('SELECT * INTO #Temp FROM ', #Environment, '.[schema].', #Table)
Hopefully this sheds more light on the problem?
Few points:
1. If you want to store the output of dynamic sql into temp table, you need to create the temp table structure first(with CREATE TABLE #TEMP script) and then you can insert data by doing something like below:
INSERT INTO #TEMP EXEC sp_executesql #Query
This will populate data into temp table with all properties of local temp table.
Seeing your query, it does not look like you have a need of dynamic sql unless you are forming some clause like where clause dynamically.
Let me know if this helps.
Couldn't you do something like this:
declare #query nvarchar(4000) = '
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[temp]'') AND type in (N''U''))
begin
drop table temp
end
Select top 2 *
into temp
from sys.databases
'
exec sp_executesql #query
Select * from temp
With Select into you don't need to know the structure of your query:
https://www.w3schools.com/sql/sql_select_into.asp
Just as an idea.

SQL OpenQuery variable tablename

I need to transfer data from a linked server to our main SQL server. The issue is, that the table name changes everyday.
I have looked around this site to find out if it is even possible to have a variable database name, which it is, but also to see if it is possible to have variables in a OPENQUERY, which it also is.
But i am struggling to combine those needs, so i have a variable table name in a OPENQUERY.
I need something like this:
Declare #LinkedServer as varchar(max) = 'LinkedServer'
Declare #TName as varchar(max) = 'TName'+substring(cast(cast(getdate() as date) as
varchar(50)),1,4)+substring(cast(cast(getdate() as date) as
varchar(50)),6,2)+substring(cast(cast(getdate() as date) as
varchar(50)),9,2)
SELECT * FROM OPENQUERY(#LinkedServer, 'SELECT * FROM dbo.#TName')
Is there any way i can make a variable table name in a OPENQUERY ?
Thank you for your help.
/Mikkel
I'd write a synonym which gets updated every day before you kick off your data extraction job. Then you don't need to be updating (potentially a tonne of) references.
CREATE SYNONYM LinkedTableA
FOR
ServerName.DBName.dbo.TName20170331
SELECT * FROM LinkedTableA
The answer i have, is this:
USE [DataBase]
GO
DROP SYNONYM [dbo].[eCallByCallStat]
GO
declare #tablename varchar(50)
set #tablename = 'Server1..dbo.eCallByCallStat'+substring(cast(cast(getdate()-1 as date) as varchar(50)),1,4)+substring(cast(cast(getdate()-1 as date) as varchar(50)),6,2)+substring(cast(cast(getdate()-1 as date) as varchar(50)),9,2)
declare #sql varchar(500)
set #sql = 'CREATE SYNONYM [dbo].[eCallByCallStat] FOR ' + #tablename
exec (#sql)
This will run everymorning updating the table name in the synonym, and then we will insert that data into a prober table so we have all the data.

SQL SELECT results INTO temp table using query string

I am trying to write some dynamic SQL queries that select results into a temp table with a query string. It looks like follows:
DECLARE #SQL Varchar(4000)
SET #SQL = 'SELECT * INTO #tmp_tab FROM dbo.sometable'
EXEC(#SQL)
It doesn't give any error to run the code, but when I want to select from #tmp_tab, it says the table doesn't exist.
So I am wondering if there is any special syntax for it, or dynamic SQL doesn't support such operation?
Many thanks.
Maybe it has something to do with access. If you create a global temp table, it will work.
DECLARE #SQL Varchar(4000)
SET #SQL = 'SELECT * INTO ##tmp_tab FROM dbo.batch'
EXEC(#SQL)
SELECT * FROM ##tmp_tab

Insert result of executing dynamic query into a table

I have a dynamic query #strQuery which on executing gives a result with lots of column.
I want to insert the result from this dynamic query into a temporary table .
I am doing this because I want to perform some filtering on the temporary table and get required result .
A similar question was asked on previous thread HERE
in which a temporary table is created first and then data inserted using INSERT INTO.
I want to avoid this step due to long list of columns and also the datatypes of fields is not known to me.
select * into #tmh from
exec(#strQuery)
Error Message
Incorrect syntax near the keyword 'exec'.
How to do this ? Is it possible to be done in this way ? If not , please specify some other alternative to get store the result on executing dynamic query into a table.
Thanks.
I have faced this situation before and here is what I did:
DECLARE #strQuery nVarchar(100)
SET #strQuery='SELECT * into [tempdb].[dbo].[temptable] FROM YourTable'
EXECUTE sp_executesql #strQuery
SELECT * FROM [tempdb].[dbo].[temptable]
DROP TABLE [tempdb].[dbo].[temptable]
It works fine. Don't ask me why a FQ table name and not #temptable. I have no idea. It does not work. The only way I could get it working was using [tempdb].[dbo].[temptable]
proceed like this
select t1.name,t1.lastname from(select * from table)t1.
where "select * from table" is your dyanmic query. which will return result which you can use as temp table t1 as given in example .
You can use variables in your current execution context, set by the Dynamic SQL with the OUTPUT option. Sample code below.
DECLARE #Amount AS MONEY
DECLARE #SQL AS NVARCHAR(1000)
SET #Amount = NULL
SET #SQL = ('SELECT #amt=100' )
EXECUTE sp_executeSQL #SQL, N'#amt MONEY OUTPUT', #amt=#Amount OUTPUT
SELECT #Amount
Yes you can make a new dynamic query containing the original query with the insert like this:
declare #strNewQuery varchar(max)
set #strNewQuery ='select * into #tmh from ('+#strQuery+') as t'
exec(#strNewQuery)
I used this to work around - with out dynamic query
This uses a table variable to receive data to procedure
Even joins can be applied to it
select * into #itemPhantom from #tbl_items_upload
select * from #itemPhantom
select #itemPhantom.itemreference from #itemPhantom left join phantom on phantom.name=#itemPhantom.PhantomName