How to SELECT * INTO [tmp table] without declare table? - sql-server-2005

i want use select statement on the a table and inserting result into a temp table variable, but i don't declare temp table with columns and i want use like this:
Declare #tmp table;
SELECT * INTO #tmp FROM myTable
this want declare columns and data types for #tmp
please help me

You can do this simply without the DECLARE command - which is not valid for #temp tables anyway, only #table variables. Did you try just the following without trying to define #tmp first:
SELECT * INTO #tmp FROM myTable;

With data:
select *
into #tmp
from myTable
No data:
select *
into #tmp
from myTable
where 0=1
BTW, you can not do this with table variables.
select *
into #tmp
from myTable
Table variables need to be declared with the columns.

Related

Create a temp table with pre-filled columns

Im trying to create a temp table #TempTable with columns. There are many columns and I do not want to type them all out by hand. Is there a way to pre-fill, if that makes sense?
Instead of
CREATE #TempTable (col1, col2 ... col1000) -- Im not saying we have 1000
But doing:
CREATE #TempTable (SELECT column_name
from information_schema.columns where table_name = 'OriginalTable')
Is this possible? Im using MS SQL.
You can do SELECT . . . INTO :
SELECT ot.* INTO #TempTable
FROM OriginalTable ot
WHERE 1 = 0;
Note : When using the SELECT . . . INTO statement, the #TempTable must not already exist.
When creating a temp table, it's good to clean up before creating it. repeating this step will cause an error if the table already exists
IF OBJECT_ID('tempdb..#tmp') IS NOT NULL
DROP TABLE #tmp
select *
into #tmp
from OriginalTable
One way of doing -
select top 0 * into #TempTable from OriginalTable
The above creates an empty copy of temp table
If you don't want to specify *(wildcard) and want specific columns from OriginalTable to be created in your temporary table -
select top 0 col1,col2,col3 into #TempTable from OriginalTable

How to execute this SQL Query

I am having following scenario
Drop Table #Temp
Create Table #Temp(name1 text, name2 text)
Insert INTO #Temp Values ('test','test')
Insert INTO #Temp Values ('test','test')
Insert Into #Temp1 Select * From
(
;With CTE as (
Select * from #Temp
)
select * from CTE
)
I know we can't use CTE as subquery .. but for hard time I don't know exact syntax of subquery since it is being provided by other system.
just image this
Insert Into #Temp1 Select * From
(
"Query Provided by Other System"
)
So I don't have any control on subquery ("Query Provided by Other System").. And I have also tried dynamic sql query like
Declare #subquery nvarchar(max)
set #subquery=';With CTE2 as ( Select * from #Temp) select * from CTE2'
INSERT INTO #Temp1 From (EXEC sp_executesql #subquery)
This also gives error...
More Things to know:
i)I don't know about what are the columns will sub query returns
ii)And I don't have any control in sub query . like what is syntax of subquery and how it looks like?
so from these things, even I can't use dynamic sql (EXEC sp_executesql).because I don't know what will happen if #subquery itself contains dynamic sql.
Please help anyone...
Use like this, with dynamic sql. It will work...
Insert Into #Temp1
EXEC sp_executesql #subquery
You can use the below syntax
;With CTE as (
Select * from #Temp
)
Insert Into #Temp1
Select *
From (
select * from CTE
) t
or if you don't have already created the #Temp1 table, use below code. It will automatically create the #temp1 table according to the selected fields
;With CTE as (
Select * from #Temp
)
Select *
Into #Temp1
From (
select * from CTE
) t
Besides syntax, you can simplify above SQL code as follows
;With CTE as (
Select * from #Temp
)
Insert Into #Temp1
Select *
From CTE
or better
Insert Into #Temp1
Select * from #Temp

Update a column in a table repeatedly

I have a table like this
CREATE TABLE #tmp(ColSelect NVARCHAR(400),ColParValues XML)
that ColSelect contains SQL Select Statement and ColParValues contains some xml data for parameter value in ColSelect
for example ColSelectcontains:
"SELECT [$12]+19/[$16]-[$54]"
and col 2 contains name value pair that refer to ColSelect parameters
How can I update my table that replace each parameter with relevant value from ColParValues. I use this statement:
update #tmp
SET
ColSelect=REPLACE(ColSelect,c.value('#Value','nvarchar(10)'),c.value('#Res','DECIMAL(24,12)'))
FROM #tmp t1
CROSS APPLY t1.ColParValues.nodes('/root/r') AS n(c)
but this statement replace just one parameter value in each row.
And this is sample data link
This is one solution :
create table #tmp (colselect varchar(200),colparvalues xml)
insert into #tmp (colselect,colparvalues)
values ('select case when [$71]+[$29]+10<25 then 1 else 0 end'
,'<root><r Value="[$71]" Res="1"/><r Value="[$29]" Res="5"/></root>'),
('select case when [$95]*[$29]+10<25 then 1 else 0 end'
,'<root><r Value="[$95]" Res="3"/><r Value="[$29]" Res="5"/></root>')
WHILE ##ROWCOUNT >0
update #tmp
SET
ColSelect=REPLACE(ColSelect,c.value('#Value','nvarchar(10)'),c.value('#Res','DECIMAL(24,12)'))
FROM #tmp t1
CROSS APPLY t1.ColParValues.nodes('/root/r') AS n(c)
WHERE t1.colselect LIKE'%'+replace(c.value('#Value','nvarchar(10)'),'[','')+'%'
select * from #tmp
drop table #tmp
However, very much similar to cursor in performance. Check the performance. Use if ok.

Dynamic sql using table variable -TSQL

My problem is using a table variable in a exec.
declare #sort_col nvarchar(1000) = 'itm_id'
declare #sort_dir nvarchar(4) = 'desc'
declare #filters nvarchar(1000) = ' and itm_name like ''%aa%'''
declare #temp table
(
itm_id int
)
insert into #temp
EXEC('select itm_id from Tblitm where itm_name not like ''%aa%''')
EXEC('select * from (select (ROW_NUMBER() OVER (ORDER BY '+#sort_col+' '+#sort_dir+')) row_num, * FROM (select itm_id, itm_name,
dbo.fnItmsHistory(itm_id) itm_history
from dbo.Tblitm as itm
left outer join '+#temp+' as temp on itm.itm_id = temp.itm_id
where itm_id=itm_id and temp.itm_id = null '+#filters+') as x) as tmp')
It says Must declare the scalar variable "#temp" when the temp table is declared i tried using original temp table and it worked, but i had problems when trying to update my entity model.So is there any solution for this problem?
Note:
I must use exec because in filters i store string for the where clause.
Try moving the table variable inside the dynamic statement.
EXEC('
declare #temp table
(
itm_id int
)
insert into #temp
select itm_id from Tblitm where itm_name not like ''%aa%''
select * from (select (ROW_NUMBER() OVER (ORDER BY '+#sort_col+' '+#sort_dir+')) row_num, * FROM (select itm_id, itm_name,
dbo.fnItmsHistory(itm_id) itm_history
from dbo.Tblitm as itm
left outer join #temp as temp on itm.itm_id = temp.itm_id
where itm_id=itm_id and temp.itm_id = null '+#filters+') as x) as tmp')
For solution i had to use a temp table and then on the start of my stored procedure i used the if condition from the EF can't infer return schema from Stored Procedure selecting from a #temp table anwser.
It's the best solution for this scenario i think.

create temp table of trigger data

I am trying to create an audit trigger without having to specifiy the column list more than once.
To this end, I want to product a temporary table of the content of the INSERTED or DELETED data in the trigger, then process that into an audit table.
If I use this:
IF #ChangeType = 'D'
SELECT * INTO #tmp FROM DELETED
ELSE
SELECT * INTO #tmp FROM INSERTED
Then I get a compilation error at the 2nd SELECT * INTO that the table #tmp already exists.
If I try and work around this using dynamic SQL:
SET #Sql = 'SELECT * INTO #tmp FROM '
IF #ChangeType = 'D'
SET #Sql = #Sq + 'DELETED'
ELSE
SET #Sql = #Sql + 'INSERTED'
EXEC (#Sql)
Then I get an error that the DELETED and INSERTED tables do not exist.
How can I get the INSERTED and DELETED tables in a trigger into a temporary or other in-memory table?
Try to create the temporary table outside the if, like:
SELECT TOP 0 * INTO #tmp FROM DELETED
IF #ChangeType = 'D'
INSERT INTO #tmp SELECT * FROM DELETED
ELSE
INSERT INTO #tmp SELECT * FROM INSERTED
This is a known problem due to the resolve-on-parse of the temp table object. With two SELECT - INTO statements in the same scope, SQL Server throws the towel.
SELECT * INTO #tmp FROM DELETED WHERE 1=0
IF #ChangeType = 'D'
INSERT #tmp SELECT * FROM DELETED
ELSE
INSERT #tmp SELECT * FROM INSERTED
I'd be interested as to why you need to copy the data into another table in the first place. But, that's off-topic...
Temporary table (#temp) are notionally stored on disc, and Table Variables (#temp) are notionally only in memory and may be more optimal for small tasks. (Assumes writes to the table will normally only affect small numbers of rows.)
Temporary tables, however, can be created using the SELECT INTO trick, avoiding the need to know the table definition in advance.
If you do know the table definition in advance, however, can't you simply use something such as the following?
DECLARE #temp TABLE (id AS INT, val as INT)
IF #ChangeType = 'D'
INSERT INTO #temp SELECT * FROM DELETED
ELSE
INSERT INTO #temp SELECT * FROM INSERTED
Personally, I'd even avoid using * if possible. Your subsequent queries will only use specific fields, so I'd only copy the fields I was using. This has the added benefit that if fields are added to the table, the code doesn't break...
DECLARE #temp TABLE (id AS INT, val as INT)
IF #ChangeType = 'D'
INSERT INTO #temp SELECT id, val FROM DELETED
ELSE
INSERT INTO #temp SELECT id, val FROM INSERTED
In my mind, the advantage of specifying the fields (which is what you wish to avoid), is that you can ensure that you always only copy what you need.