Creating a dynamic table from dynamic SQL - sql

First of all I'm using ms SQL server 2012. I' trying to use a table based on a string value passed in as a string into a procedure. I found out that you can't use strings are table names when writing a query so I'm trying to find a way around that. The only lead I'm kind of onto is using dynamic SQL which I also am not sure how to make work. Here is what I have:
DECLARE #q AS NVARCHAR(MAX)
SET #q = 'SELECT * FROM ' + #tableName
DECLARE #tableCopy AS EXECUTE(#q)
How can I get the executed #q into #tableCopy? Or is there a better way to access my table when all I know is the tables name as a string?

You can create the temporary table and then insert into that table inside the dynamic sql. There's an example here:
http://smehrozalam.wordpress.com/2009/10/14/t-sql-using-result-of-a-dynamic-sql-query-in-a-variable-or-table/
Unfortunately, you would need to know the schema. The following does not work:
declare #query varchar(max) =
'select * into #t from table'
EXEC(#query)
select * FROM #t

Related

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 Server - select into from statement?

I have this query in SQL Server:
select column
from table_53;
Now, I want to get this 53 from another table, so what I want to do is something like this:
select column
from table_(select id from table2);
Is there any way to do this in SQL Server?
This is definitely not the way SQL thinks and works. Maybe your suggested approach can be mimicked by way of writing stored procedures in which you create SQL-statements which are then evaluated. However, this will not be very efficient.
A better approach would be to store the values of all your individual separate tables into one master table and mark them in a separate column tblid with their number (e.g. 53). Then you can always filter them from this master table by looking for this tblid.
You need dynamic sql query here.
declare #sqlQuery = 'select column
from table_(';
set #sqlQuery = #sqlQuery + 'select id from table2)';
EXEC (#sqlQuery)
Note :- One of cons of using dynamic sql query is sql injection. I would suggest to have better table structure or try to used parameterized query.
Yes, you can, but using something like this:
DECLARE #ID INT;
DECLARE #QUERY NVARCHAR(MAX);
SELECT #ID = ID FROM TABLE_2;
--IF #ID EQUALS 53 THEN
SET #QUERY = 'SELECT COLUMN FROM TABLE_' + CAST(#ID AS NVARCHAR(10));
-- #QUERY EQUALS TO 'SELECT COLUMN FROM TABLE_53'
EXEC (#QUERY);

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

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

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