renaming a temporary table into a physical one - sql

Can I do something like this?
create table #tbl_tmp (col1 int)
insert into #tbl_tmp select 3
exec sp_rename '#tbl_tmp','tbl_new'

No.
If you are running this from a database other than tempdb you get
No item by the name of '#tbl_tmp' could be found in the current
database ....
Which is not surprising as all the data pages etc. are in the tempdb data files so you wouldn't be able to rename this to suddenly become a permanent table in an other database.
If you are running this from tempdb you get
An invalid parameter or option was specified for procedure
'sys.sp_rename'.
If you do EXEC sp_helptext sp_rename and look at the definition the relevant bit of code disallowing this is
--------------------------------------------------------------------------
-------------------- PHASE 32: Temporay Table Isssue -------------------
--------------------------------------------------------------------------
-- Disallow renaming object to or from a temp name (starts with #)
if (#objtype = 'object' AND
(substring(#newname,1,1) = N'#' OR
substring(object_name(#objid),1,1) = N'#'))
begin
COMMIT TRANSACTION
raiserror(15600,-1,-1, 'sys.sp_rename')
return 1
end
Why wouldn't you just create a permanent table in the first place then do the rename?

As far as I know this is not possible outside of tempdb.
Instead of renaming the table, you can create a new one from the temporary one.
Untested:
SELECT *
INTO tbl_new
FROM #tbl_tmp

The answer is Yes. You can implement something like it but in a workaround way.
Try the following approach, a lil bit old school but bypasses the restriction. I tested it myself as well
/* Create an empty temporary staging table **/
use aw_08r2
go
-- create temporary table
select * into #temp from person.address
-- select data from temporary staging table
select * from #temp
-- convert the temporary table and save as physical table in tempdb
select * into tempdb.dbo.test from #temp
-- save a copy of the physical table from tempdb in aw_08r2
select * into person.test from tempdb.dbo.test
-- select data from physical table
select * from #temp
select * from tempdb.dbo.test
select * from person.test
-- drop temporary table and physical table from tempdb
drop table #temp
drop table tempdb.dbo.test
go

Related

How can I view the definition of a temporary table?

I make a temporary table in SQL Server:
create table #stun (name varchar(40),id int,gender varchar(40))
How can I view its definition afterwards?
you can check this way-
SELECT *
INTO #TempTable
FROM table_name -- any table from database
EXEC tempdb..sp_help '#TempTable'
DROP TABLE #TempTable
Solution 1 :
You can query data against it within the current session :
SELECT
*
FROM
#yourtemporarytable;
Sometimes, you may want to create a temporary table that is accessible across connections. In this case, you can use global temporary tables.
Unlike a temporary table, the name of a global temporary table starts with a double hash symbol (##).
CREATE TABLE ##global_temp (
...
);
SELECT
*
FROM
##global_temp
Solution 2 :
Using SSMS, you can find the table in the left pane >> Design >> get the table structure.

Cloning a table definition to a table variable in SQL Server

Is there a way to clone the table definition from an existing table and recreate as a table variable?
DECLARE #TempTable1 TABLE (ID INT, Description VARCHAR(256))
I need to recreate a set of tables with same number of columns and definitions without repeating the DECLARE TABLE statement.
This process is available on MySQL as below.
CREATE TABLE TempTable1 LIKE TempTableMain;
Is it possible to do this is Microsoft SQL Server?
Please note that the actual scenario contains more that 60 columns in the #TempTable and need to create more than 10 instances from the original table.
I am not talking about data insertion or SELECT ion from another table as below. I need to create the table definition.
DECLARE #TempTable TABLE(ID INT, Description VARCHAR(100))
INSERT INTO #TempTable
VALUES (1, 'Test1'), (1, 'Test1');
SELECT *
INTO #TempTable2
FROM #TempTable1
SELECT * FROM #TempTable2
Create a user defined type with the columns of your table, lets say like that:
CREATE TYPE MyTableType AS TABLE (ID INT, Description VARCHAR(256));
And then declare your table variables using this type:
DECLARE #Table1 MyTableType;
DECLARE #Table2 MyTableType;
DECLARE #Table3 MyTableType;
SQL Server management studio gives you the option to create a sql script to create an already existing table.
Right click your table -> script table as -> CREATE To -> New Query Editor window
This way you dont have to write out the whole query every single time.
You could even create a stored procedure which takes as argument the name of your to be created table and run this from a while loop.
You can perform the following command:
SELECT * INTO #MyTable_tmp FROM MyTable
Then modify your MyTable, and copy your data back in. Other approaches I've seen is to create a new table calling it Mytable_Tmp (Not a temp table), which will be your new table.
Then copy your data doing any migrations you need. Then you will drop the original table and do a rename on Mytable.
When you run SELECT * INTO #MyTable FROM MyTable, SQL Server creates a new temporary table called #MyTable that matches each column and data type from your select clause. In this case we are selecting * so it will match MyTable. This only creates the columns it doesn't copy defaults, constraints indexes or anything else.
If you are using table variables, it means that you don't want to use them in long period of time, as they will be "forgotten" after every script completion.
So, easiest in my opinion is to use such construct:
IF OBJECT_ID('tempdb.dbo.#tmpTable', 'U') IS NOT NULL
DROP TABLE #tmpTable;
SELECT * INTO #tmpTable FROM MyPrimaryTable
It creates temporary table exactly like yours, if you want empty table, you can just use:
SELECT * INTO #tmpTable FROM MyPrimaryTable WHERE 1 = 0
Then, temporary table will have exact same schema as your primary table.
You can apply as many times as you need (create as many temporary tables as you need).
You could use regular tables instead of temporary tables as well.
If you want to re-create table after dropping the existing table then you can use the below query.
/*
Create brands table
*/
-- Old block of code
IF EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'[TOY].[BRANDS]') AND type in (N'U'))
DROP TABLE [TOY].[BRANDS]
GO
-- New block of code
DROP TABLE IF EXISTS [TOY].[BRANDS]
GO
-- Add new table
CREATE TABLE TOY.BRANDS
(
ID INT NOT NULL,
NAME VARCHAR(20) NULL
)
GO
-- Load the table with data
INSERT INTO TOY.BRANDS (ID, NAME) VALUES
(1, 'Ford'),
(2, 'Chevy'),
(3, 'Dodge'),
(4, 'Plymouth'),
(5, 'Oldsmobile'),
(6, 'Lincoln'),
(7, 'Mercury');
GO

There is already an object named '#DIR_Cat' in the database

In my Stored procedure, I have added a command to create a hash temp table #DIR_CAT. But every time I execute the procedure I get this error:
"There is already an object named '#DIR_Cat' in the database."
Even when I have already created an Exists clause at the start of SP to check and drop the table if it is present. Any help is much appreciated.
The code goes like this.
if exists (select * from dbo.sysobjects where id = object_id(N'#DIR_Cat') )
drop table #DIR_Cat
/* some lines of code*/
CREATE TABLE #DIR_Cat (XMLDta xml)
/* some lines of code*/
INSERT #DIR_Cat exec (#stmt)
/* some lines of code*/
drop table #DIR_Cat
Main issue is you're not fully qualifying your objects. Your temp table lives in tempdb, whereas the system views use whatever database you're currently connected to by default. So essentially you're looking for the temp table, but you're looking in whatever database your currently connected to (which I'm guessing is not tempdb).
I'm assuming you're using SQL Server here, although you did also mention mysql in the tags. If that's what you're using, this code may not apply.
Here's the snippet I use for temp table drop/create
if object_id('tempdb.dbo.#<TableName, sysname, >') is not null drop table #<TableName, sysname, >
create table #<TableName, sysname, >
(
)
Side note, don't use dbo.sysobjects. That's a really old compatibility view. If you want to use objects, use sys.objects instead.
temp table does not exists in local DB sys.objects, it is in tempdb
you need to query tempb.sys.objects
the name of the temp table does not appear exactly as it is in the tempdb.sys.objects.
You can't query it just like
select *
from tempdb.sys.objects
where name = '#DIR_Cat' -- This does not works
you need to use object_id()
select *
from tempdb.sys.objects
where object_id = object_id('tempdb..#DIR_Cat')

Finding #temp table in sysobjects / INFORMATION_SCHEMA

I am running a SELECT INTO statement like this so I can manipulate the data before finally dropping the table.
SELECT colA, colB, colC INTO #preop FROM tblRANDOM
However when I run the statement and then, without dropping the newly created table, I then run either of the following statements, the table isn't found? Even scanning through object explorer I can't see it. Where should I be looking?
SELECT [name] FROM sysobjects WHERE [name] = N'#preop'
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '#preop'
Temp tables aren't stored in the local database, they're stored in tempdb. Also their name isn't what you named them; it has a hex code suffix and a bunch of underscores to disambiguate between sessions. And you should use sys.objects or sys.tables, not the deprecated sysobjects (note the big warning at the top) or the incomplete and stale INFORMATION_SCHEMA views.
SELECT name FROM tempdb.sys.objects WHERE name LIKE N'#preop[_]%';
If you are trying to determine if such an object exists in your session, so that you know if you should drop it first, you should do:
IF OBJECT_ID('tempdb.dbo.#preop') IS NOT NULL
BEGIN
DROP TABLE #preop;
END
In modern versions (SQL Server 2016+), this is even easier:
DROP TABLE IF EXISTS #preop;
However if this code is in a stored procedure then there really isn't any need to do that... the table should be dropped automatically when the stored procedure goes out of scope.
I'd prefer to query tempdb in such manner:
IF EXISTS (SELECT * FROM tempdb.sys.objects
WHERE object_id = OBJECT_ID(N'tempdb.[dbo].[#MyProcedure]')
AND type in (N'P', N'PC'))
BEGIN
print 'dropping [dbo].[#MyProcedure]'
DROP PROCEDURE [dbo].[#MyProcedure]
END
GO
Below is how I got the columns for a temporary table:
CREATE TABLE #T (PK INT IDENTITY(1,1), APP_KEY INT PRIMARY KEY)
SELECT * FROM tempdb.INFORMATION_SCHEMA.COLUMNS c WHERE c.TABLE_NAME LIKE '#T%'

Best way to create a temp table with same columns and type as a permanent table

I need to create a temp table with same columns and type as a permanent table. What is the best way to do it? (The Permanent table has over 100 columns)
i.e.
Usually I create table like this.
DECLARE #TT TABLE(
member_id INT,
reason varchar(1),
record_status varchar(1) ,
record_type varchar(1)
)
But is there any way to do it without mentioning the column names and type, but mention the name of another table with the required columns?
select top 0 *
into #mytemptable
from myrealtable
I realize this question is extremely old, but for anyone looking for a solution specific to PostgreSQL, it's:
CREATE TEMP TABLE tmp_table AS SELECT * FROM original_table LIMIT 0;
Note, the temp table will be put into a schema like pg_temp_3.
This will create a temporary table that will have all of the columns (without indexes) and without the data, however depending on your needs, you may want to then delete the primary key:
ALTER TABLE pg_temp_3.tmp_table DROP COLUMN primary_key;
If the original table doesn't have any data in it to begin with, you can leave off the "LIMIT 0".
This is a MySQL-specific answer, not sure where else it works --
You can create an empty table having the same column definitions with:
CREATE TEMPORARY TABLE temp_foo LIKE foo;
And you can create a populated copy of an existing table with:
CREATE TEMPORARY TABLE temp_foo SELECT * FROM foo;
And the following works in postgres; unfortunately the different RDBMS's don't seem very consistent here:
CREATE TEMPORARY TABLE temp_foo AS SELECT * FROM foo;
Sortest one...
select top 0 * into #temptable from mytable
Note : This creates an empty copy of temp, But it doesn't create a primary key
select * into #temptable from tablename where 1<>1
Clone Temporary Table Structure to New Physical Table in SQL Server
we will see how to Clone Temporary Table Structure to New Physical Table in SQL Server.This is applicable for both Azure SQL db and on-premises.
Demo SQL Script
IF OBJECT_ID('TempDB..#TempTable') IS NOT NULL
DROP TABLE #TempTable;
SELECT 1 AS ID,'Arul' AS Names
INTO
#TempTable;
SELECT * FROM #TempTable;
METHOD 1
SELECT * INTO TempTable1 FROM #TempTable WHERE 1=0;
EXEC SP_HELP TempTable1;
METHOD 2
SELECT TOP 0 * INTO TempTable1 FROM #TempTable;
EXEC SP_HELP TempTable1;