Is it possible to apply SELECT INTO a temporary table from another SELECT? - sql

For some performance improvements, I am looking at using a temporary table rather than a table variable
I am currently putting 100,000s or rows into a table variable using INSERT INTO #table EXECUTE sp_executesql #SQLString (where #SQLString returns a string 'SELECT 'INSERT INTO LiveTable Values('x','y','z') build by dynamic SQL so that the x,y,z values are from the real records)
The INSERT INTO takes a bit of time and I was wondering if, having read about how much better SELECT * INTO #tempTable is, can you do a SELECT * INTO with another SELECT as the source?
So something like
SELECT * INTO #tempTable FROM (SELECT * FROM Table2)

The problem with your query is that all subqueries need a table alias in SQL:
SELECT *
INTO #tempTable
FROM (SELECT * FROM Table2) t;

Short answer is yes (I believe I have done this before, awhile ago, but I don't recall any issues). You can get some more information from this post on msdn:
http://social.msdn.microsoft.com/Forums/sqlserver/en-US/92e5fdf0-e2ad-4f1c-ac35-6ab1c8eec642/select-into-localvarname-from-select-subquery

SELECT * INTO #tempTable FROM (SELECT * FROM Table2)T
SELECT * INTO #tempTable FROM Table2

SELECT * INTO #TempTable
FROM table_name
Yes you can do this, Point to be noted is this #TempTable will be created on the fly, meaning if there is a Temp table that already exists using this error will throw an error as it will try to create a Temp table 1st and then insert the data into it.
To insert data into a table that already exist you will have to use INSERT INTO syntax, something like
INSERT INTO #TempTable --<-- When using this syntax it is best practice to always
SELECT Col1, COl2, .... -- mention the Column names in INSERT INTO and SELECT
FROM TableName -- rather then using SELECT * to makes sure data is being
-- selected from and insert into the RIGHT columns
since you have mentioned you are using it with a stored procedure and would like to use make use of this syntax with store procedure, Im sorry you will not be able to do anything like
SELECT * INTO #Temp Execute usp_Proc
for this you will have to stick with
INSERT INTO #TempTable Execute usp_Proc
The Temp table has to exists before you can insert data into it from a stored Procedure.

Related

storing query outputs dynamically TSQL

I have a loop over different tables which returns results
with different number of columns.
Is it possible to store the output of a query without creating a concrete table?
I've read some posts regarding temporary tables so I tried this simple example:
create table #temp_table1 (id int)
insert into #temp_table1 ('select * from table1')
table1 above could be any table
I get the following error message:
Column name or number of supplied values does not match table definition.
Is there anyway to avoid having hard code table definitions exactly matching the output of your query?
Thanks!
You could do a select into - that will create the temporary table automatically:
SELECT * INTO #Temp
FROM TableName
The problem is that since you are using dynamic SQL , your temporary table will only be available inside the dynamic SQL scope - so doing something like this will result with an error:
EXEC('SELECT * INTO #Temp FROM TableName')
SELECT *
FROM #Temp -- The #Temp table does not exists in this scope!
To do this kind of thing using dynamic SQL you must use a global temporary table (that you must drop once done using!):
EXEC('SELECT * INTO ##GlobalTempFROM TableName')
SELECT * INTO #Temp
FROM ##GlobalTemp -- Since this is a global temporary table you can use it in this scope
DROP TABLE ##GlobalTemp

Declaring Table Variable using Existing Table Schema in Sql

I want to declare a Table Variable in my stored procedure using existing tables schema.
I have a Table, say TableA, which has about 30 columns.
I want to declare a Table Variable using the same columns just as we declare a Temporary Table.
For instance,
I can declare a Temporary Table using the schema like this:
SELECT TOP 0 * INTO #Temp_TableA FROM TableA
Can I similarly declare a Table Variable???
From MSDN:
No, table variable is a variable as name suggests so you need to declare it before you can use it like all other T-SQL variables and you need to use INSERT INTO
DECLARE #MyTable TABLE(
ID INT NOT NULL,
Data varchar(30) NOT NULL
);
INSERT INTO #MyTable
SELECT ID, data
From <table>
You can also use a temporary table in your stored procedure. Just add to the beginning of stored procedure this code:
if object_id('tempdb..#TableA') is not null drop table #TableA
You should use a CTE for this purpose:
; with CTE as (SELECT TOP 0* FROM TableA)
SELECT * FROM CTE
The only thing to remember is CTE can only be used in the next line after the initialization. So for example, the following won't work-
; with CTE as (SELECT TOP 0* FROM TableA)
SELECT * FROM TableA
SELECT * FROM CTE
because here CTE will become invalid.
DECLARE A Table Variable having same as SCHEMA of your table first and then INSERT INTO syntax as mentioned by Megatron.
If you are planning to use inside a stored procedure, then use CTE and don't forget to mention ; befire CTE declareation and insert into CTE variable from your table.

SELECT against stored procedure SQL Server

SELECT Val from storedp_Value within the query editor of SQL Server Management Studio, is this possible?
UPDATE
I tried to create a temp table but it didn't seem to work hence why I asked here.
CREATE TABLE #Result
(
batchno_seq_no int
)
INSERT #Result EXEC storedp_UPDATEBATCH
SELECT * from #Result
DROP TABLE #Result
RETURN
Stored Procedure UpdateBatch
delete from batchno_seq;
insert into batchno_seq default values;
select #batchno_seq= batchno_seq_no from batchno_seq
RETURN #batchno_seq
What am I doing wrong and how do I call it from the query window?
UPDATE #2
Ok, I'd appreciate help on this one, direction or anything - this is what I'm trying to achieve.
select batchno_seq from (delete from batchno_seq;insert into batchno_seq default values;
select * from batchno_seq) BATCHNO
INTO TEMP_DW_EKSTICKER_CLASSIC
This is part of a larger select statement. Any help would be much appreciated. Essentially this SQL is broken as we've migrated for Oracle.
Well, no. To select from a stored procedure you can do the following:
declare #t table (
-- columns that are returned here
);
insert into #t(<column list here>)
exec('storedp_Value');
If you are using the results from a stored procedure in this way and you wrote the stored procedure, seriously consider changing the code to be a view or user defined function. In many cases, you can replace such code with a simpler, better suited construct.
This is not possible in sql server, you can insert the results into a temp table and then further query that
CREATE TABLE #temp ( /* columns */ )
INSERT INTO #temp ( /* columns */ )
EXEC sp_MyStoredProc
SELECT * FROM #temp
WHERE 1=1
DROP TABLE #temp
Or you can use OPENQUERY but this requires setting up a linked server, the SQL is
SELECT * FROM (ThisServer, 'Database.Schema.ProcedureName <params>')
The best article (in my opinion) about all possible methods for sharing data between stored procedures in SQL Server you can find here: http://www.sommarskog.se/share_data.html
Try this
Change 'Return'
delete from batchno_seq;
insert into batchno_seq default values;
select #batchno_seq= batchno_seq_no from batchno_seq
RETURN #batchno_seq
to 'Select'
delete from batchno_seq;
insert into batchno_seq default values;
select #batchno_seq= batchno_seq_no from batchno_seq
SELECT #batchno_seq
My approach
select * into new_table from (select t1.col1,t1.col2,..
from table1 t1
union
select t2.cola,t2.colb,..
from table2 t2) as union_table
I MUST be missing something.
Since your stored procedure does not return a result set, and instead returns an integer, using the RETURN functionality of stored procs, you simply CANNOT INSERT into ANY table (since there isn't any result set coming back, at all).
BUT, you can (assuming that this is done iteratively, and not over a set) simply store the return value into a local variable, and insert that variable's value into whatever table is necessary.
However, if you simply want to return the value in the results of a Query Window in SSMS, doing the INSERT and SELECTING is overkill.
It seems to me like THIS would suffice (in a query window):
DECLARE #RetVal INT = 0;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
EXEC #RetVal = storedp_UPDATEBATCH;
COMMIT TRANSACTION;
SELECT #RetVal;
--OR
--PRINT #RetVal;
If this is way far off base, please provide the DDL for "batchno_seq", maybe I can be of better assistance that way.
Cheers!

Querying results of a stored procedure

I have a stored procedure that returns a large number of results, and would like a better way to debug/ parse the results than copy/pasting into excel or whatever - is there a way to pass the results of the procedure into a query? e.g., if the procedure call was something like:
exec database..proc 'arg1','arg2','arg3'
my thought was to do something like:
select distinct column1 from
(exec database..proc 'arg1','arg2','arg3')
which clearly did not work, or I wouldn't be here. If it matters, this is for a sybase database.
Thanks!
The code below works in MS SQL 2005. I don't have a Sybase installation right now to test it on that. If it works in Sybase you could use a temporary table (or permanent table) outside of your stored procedure so that you don't have alter the code that you're trying to test (not a very good testing procedure generally.)
CREATE TABLE dbo.Test_Proc_Results_To_Table
(
my_id INT NOT NULL,
my_string VARCHAR(20) NOT NULL
)
GO
CREATE PROCEDURE dbo.Test_Proc_Results_To_Table_Proc
AS
BEGIN
SELECT
1 AS my_id,
'one' AS my_string
END
GO
INSERT INTO dbo.Test_Proc_Results_To_Table (my_id, my_string)
EXEC dbo.Test_Proc_Results_To_Table_Proc
GO
SELECT * FROM dbo.Test_Proc_Results_To_Table
GO
In SQL Anywhere 10 and 11(didn't see whether it's ASA or ASE you're asking about):
SELECT DISTINCT Column1
FROM procName(parameter1, parameter2, parameter3);
I don't have ASE, and I'm not sure if this works on earlier ASA versions.
you could create a temporary table (#temp) in the sp and populate the result set in there. You can later select from the same temp table from the same session. (Or use a global temp table in sybase with ##temp syntax)
This is because what you want to do (select * from exec sp) is not directly possible in sybase
Is it possible to rewrite the stored proc as a function that returns a table? On SQL Server this is certainly possible. Then you can do...
select
<any columns you like>
from
dbo.myFunc( 'foo', 'bar', 1 )
where
<whatever clauses you like>
order by
<same>
I'm not familiar with Sybase, but in MySQL you could use the IN parameter to write one SQL query for all this. Ex:
select distinct column1 from table where column1 in (your_first_query_with_all_the_arguments)
I don't have Sybase installed right now, so some minor syntactic aspect may be wrong here - I can't check, but I used it extensively in the past: select * into #temp from proc_name('arg1','arg2','arg3') should create the local temp table for you automatically with the right columns. Within the same transaction or begin/end block you can access #temp by select * from #temp.
The only real way around this problem is to create a table in your database to store temporary values.
Lets say the stored procedures selects Column1, Column2 & Column3.
Have a table (tempTable) with Column1, Column2, Column3 and set your stored procedure to the following:
CREATE PROCEDURE database..proc
AS
BEGIN
DELETE FROM tempTable
INSERT INTO tempTable (Column1, Column2, Column3)
SELECT Column1, Column2, Column3
FROM Table1
END
then for your sql code to select the values have:
exec database..proc
SELECT Column1, Column2, Column3
FROM tempTable
I hope this helps, I've come across similar problems before and this was the best I could work out.

Problem with SELECT INTO using local variables

I need to create an SQL query to insert some data into a table based on the results of a SELECT query into a local variable. My DB platform is MySQL 5.1, but I don't think that should make a difference here. Basically, what I want to do is:
SELECT id INTO var_name FROM table1 WHERE some_column='something' LIMIT 1;
INSERT INTO table2 (`number`) VALUES (#var_name);
I can't get past the first statement, though, as I get the error "Undeclared variable var_name". I've also tried putting the statement in a BEGIN/END block, and a stored procedure, but then I encounter other errors which state only that there is an error on the SELECT line. What am I doing wrong?
You need to declare #var_name and then select into #var_name. I don't know MySQL too well but try something like this:
declare #var_name varchar(100);
SELECT id INTO #var_name FROM table1 WHERE some_column='something' LIMIT 1;
INSERT INTO table2 (`number`) VALUES (#var_name);
Edit: Perhaps a better way to do it:
insert into table2 ('number')
select id
from table1
where some_column = 'something' LIMIT 1;
This negates the need for a variable and will be a lot faster and easier to understand down the road.
Try
INSERT INTO table2 (`number`)
SELECT id FROM table1 WHERE some_column='something' LIMIT 1
CREATE TABLE table_name
AS
SELECT ...(your select)