There is already an object named '##Temp' in the database - sql

I have a stored procedure on SQL Server 2000. It contains:
select ... into ##Temp ...
...
drop table ##Temp
When I run the stored procedure with ADO a second time, it prompts:
There is already an object named '##Temp' in the database.
Could anyone kindly tell me what's wrong?

You should re-write your stored proc to drop the temp table if it exists, then you won't ever have this issue
IF (SELECT object_id('TempDB..##Temp')) IS NOT NULL
BEGIN
DROP TABLE ##Temp
END

You are using a global temp table as indicated by the ## at the beginning of the table name. This means multiple sessions can access the table.
It's likely that you have a connection open that created the table, but failed to drop it. Are you sure that the first ADO run actually drop the table. Could it have failed, or did the flow control in the procedure skip the drop statement?
You may want to test the procedure in SQL Server Enterprise Manager to see if it reports any errors.

Since you chose to use a global temporary table ##Temp, it is visible to all SQL connections at any given time. Obviously, while the stored proc is running for one connection, a second connection comes in and tries to create yet another ##Temp but that already exists....
Use connection-local #Temp tables (only one #) instead.

Oh, it's all my fault. I called the SP twice through one connection by mistake.
That's why it always reports error when being called the second time.
Of course you won't know that by reading my description. Sorry guys...

For me this solution works :
IF (SELECT object_id ='#Temp') IS NOT NULL
BEGIN
DROP TABLE #Temp
END

Related

For how long does a temporary table "live" in dynamic SQL code in Msn SSMS?

I have a problem with temporary tables that does not "live" long enough in my code.
My problem looks like this: I want to create a temporary table in one "codevariable" and use it later. An example of my code structure is like below:
declare #RW varchar(MAX)
set #RW = '
select *
into #temptable
from table1'
exec(#RW)
--Alots of other code.
select *
from #temptable
This results in an error message that sais "Invalid object name '#temptable'. And it's very clear that my temporary table does'nt exists anymore. But I've checked that the table creates in the first step. For example the following code works:
declare #RW varchar(MAX)
set #RW = '
select *
into #temptable
from table1
select *
from #temptable'
exec(#RW)
So my GUESS is that the temporary table only lives within it's code variable. Is there a way to create a temporary table that lives longer? Or, do I just needs to accept this for what it is or am I missing something? I have a work around solution that is not very efficient. What I'm thinking of is creating a regular table which I later delete. This would mean a lot of writing to disks but it's something that the system I work with would survive, but not be happy with. Is there any other way to handle this?
A temporary table only persists for the duration of the scope that declared it. For a "normal" connection that will be when the connection is dropped. For example, if you're using SSMS and open a query window and run CREATE TABLE #T (ID int); it'll create the table. As you're still connected, the table won't be dropped and will still exist. If you run the statement again (without dropping it) you'll get an error that it already exists. As soon as you close that query window, the temporary table will be dropped.
For a dynamic statement, the scope is the duration of that dynamic statement. This means that as soon as the dynamic statement completes, the table will be dropped:
EXEC sys.sp_executesql N'CREATE TABLE #T (ID int);';
SELECT *
FROM #t;
Notice this errors, as the scope the table was created in has completed, and thus dropped.
If you are using dynamic statements to create temporary tables, you need to make all the references to said temporary table within the dynamic statement.
Otherwise, if you need to reference it outside of the statement, I personally find I create an "permanent" object in tempdb, and then clean up afterwards.
EXEC sys.sp_executesql N'CREATE TABLE tempdb.dbo.T (ID int);';
SELECT *
FROM tempdb.dbo.T;
DROP TABLE tempdb.dbo.T;
These tables are still dropped in the event the instance is restarted as well.
Note that "global" temporary table behave slightly differently. As global temporary table can be referenced in any connection, while it exists. This means that another connection could be using the table while the scope that created it ends. As a result a global temporary table persists until the scope that declared is ends and there are no other active connections using the object. This means that the objects could be dropped mid batch in another connection.

SQL Server temp table check performance

IF OBJECT_ID('tempdb..#mytesttable') IS NOT NULL
DROP TABLE #mytesttable
SELECT id, name
FROM
INTO #mytesttable mytable
Question: is it good to check temp table existence (e.g: OBJECT_ID('tempdb..#mytesttable') ) when I first time create this temp table inside a procedure?
What will be the best practice in terms of performance?
It is good practice to check if table exists or not. and it doesn't have any performance impact. anyhow, temp tables automatically drops once procedure execution completes in sql server. sql server appends unique num with temp table name. so if same procedure executes more than once at same time also , it will not cause any issue. it depends on session. all procs executions have different session.
Yes, it is a good practice. I am always doing this at the beginning of the routine. In SQL Server 2016 + objects can DIE (Drop If Exists), so you can simplify the call:
DROP TABLE IF EXISTS #mytesttable;
Also, even at the end of the routine you temporary objects are destroyed and even the SQL Engine gives unique names to temporary tables, there is still another behavior to consider.
If you are naming your temporary table with same name, when nested procedure calls are involved (one stored procedure calls another) it is possible to get an error or corrupt your data. This is due to the fact that temporary table are visible in the current execution scope - so, #table in one procedure will be visible in the second called procedure (so you can modify its data or drop it).

Temporary Table Scope?

I am making use of temporary tables #tempTable in my stored procedure - that I make use to run my ASP.net Reports (Reporting services)
I am doing something like
eg. Code
SELECT * INTO #tempTable FROM Contacts WHERE ContactID < 10
Then I use something like
SELECT o.* FROM #tempTable t INNER JOIN Orders o ON t.ContactID =o.ContactID
to return values to my reports aka results for the stored procedure
I do not get rid of my #tempTable
i.e. I don't do
DROP TABLE #tempTable
I have read that the scope of temporary table is only for the stored procedure - so is doing the above necessary - if I dont do the above what problems will I get into in the future
First, local temporary tables created within a procedure are dropped once the procedure finishes. From the BOL on Create Table:
A local temporary table created in a stored procedure is dropped automatically when the stored procedure is finished. The table can be referenced by any nested stored procedures executed by the stored procedure that created the table. The table cannot be referenced by the process that called the stored procedure that created the table.
If your data access code is properly opening a connection, calling a stored procedure and then closing the connection, the temp table is created in the procedure is effectively destroyed.
I say "effectively" to bring up another point. I would not recommend dropping the temp table at the end of your procedure although I would add a check just before I created the temp table and drop it if exists (e.g. if object_id('tempdb..#Foo') is not null). The argument against dropping the temp table at the end is that by calling the Drop statement, you are forcing SQL Server to expend resources to destroy the table then and there while you wait for your procedure to end. If instead, you let it go out of scope, your procedure ends immediately and you let SQL Server destroy the table at a time of its own choosing.
The #Temp table is limited scope to YOUR SESSION and lifespan of the batch, meaning nobody else can see your temp table and anyone else can create their own #Temp table with the same name. Once your session or batch ends, SQL Server will clean up the temp table.
On another note the ##Temp table behaves like a normal table. Everyone can see it, and there cannot be more than 1 ##Temp table with the same name. SQL Server will clean these ##Temp tables when the server restarts.
It's considered good coding practice to explicitly drop every temporary table you create. If you are executing scripts through SQL Server Management Studio/Query Analyzer the temp tables are kept until you explicitly drop them or until you close the session.
In general, you're probably not going to have problems by not dropping temporary tables. The local temp table has session scope, or SP scope in your case. It will drop automatically when the session is closed or the SP completes.
However, you do increase the risk of problems by regularly following this practice. For example, if you don't use an SP, but submit your SELECT statement from ASP .net and leave the SQL Server connection open, the temp table will continue to exist. Continued use of the connection and other temp tables will result in tempdb growth over time.
I also support the other comments regarding the use of temp tables in this case. If you create a solution without temp tables, you'll probably have a faster report and avoid the DROP temp table command too.

SQL: What is INSERT INTO #table?

I wanted to know what does the # symbol mean? Why is it being used?
Example:
INSERT INTO #tmpContracts (sym, contractCount)
SELECT sym,
COUNT(DISTINCT(fulloptionsym)) AS contractCount
It means it is a temporary table. Take a look at the "Temporary Table" section of the CREATE TABLE documentation.
It is a temporary table, and is only available to the current session. It will be automatically dropped when it goes out of scope. If the same code is run by multiple people at the same time, each gets their own table, like local variables, and there is no need to worry about a collision.
'#' is used for temporary table e.g : '#tmpContracts'
'##' is used for global temporary table e.g : '##tmpContracts'
Read this temporary table
A #Temp is a temp table that is active for the duration of the connection. It resides in the TempDB.
A #Temp is local (only available to the current connection) and is dropped once the connection is terminated.
A ##Temp is global (available to all connections) and is dropped once all connections using it are terminated.
corrected owing to feedback and correction from Gail
There is also a ## table type in SQL Server which is a temp table that is accessible removed when the server or the SQL Server service is restarted.
Try using
'#temp' = temperory table

View Temporary Table Created from Stored Procedure

I have a stored procedure in SQL 2005. The Stored Procedure is actually creating temporary tables in the beginning of SP and deleting it in the end. I am now debugging the SP in VS 2005. In between the SP i would want to know the contents into the temporary table. Can anybody help in in viewing the contents of the temporary table at run time.
Thanks
Vinod T
There are several kinds of temporary tables, I think you could use the table which is not dropped after SP used it. Just make sure you don't call the same SP twice or you'll get an error trying to create an existing table. Or just drop the temp table after you see it's content. So instead of using a table variable (#table) just use #table or ##table
From http://arplis.com/temporary-tables-in-microsoft-sql-server/:
Local Temporary Tables
Local temporary tables prefix with single number sign (#) as the first character of their names, like (#table_name).
Local temporary tables are visible only in the current session OR you can say that they are visible only to the current connection for the user.
They are deleted when the user disconnects from instances of Microsoft SQL Server.
Global temporary tables
Global temporary tables prefix with double number sign (##) as the first character of their names, like (##table_name).
Global temporary tables are visible to all sessions OR you can say that they are visible to any user after they are created.
They are deleted when all users referencing the table disconnect from Microsoft SQL Server.
Edit the stored procedure to temporarily select * from the temp tables (possibly into another table or file, or just to the output pane) as it runs..?
You can then change it back afterwards. If you can't mess with the original procedure, copy it and edit the copy.
I built a few stored procedures which allow you to query the content of a temp table created in another session.
See sp_select project on github.
The content of the table can be displayed by running exec sp_select 'tempdb..#temp' from no matter which session.
Bottom line: the default Visual Studio Microsoft debugger is not in the same session as the SQL code being executed and debugged.
So you can ONLY look at #temp tables by switching them to global ##temp tables or permanent tables or whatever technique you like best that works across sessions.
note: this is VERY different from normal language debuggers... and I suspect kept
that way by Microsoft on purpose... I've seen third party SQL debugger tools decades ago
that didn't have this problem.
There is no good technical reason why the debugger cannot be in the same session as your SQL code, thus allowing you to examine all produced contructs including #temp tables.
To expand on previous suggestions that you drop the data into a permanent table, you could try the following:
-- Get rid of the table if it already exists
if object_id('TempData') is not null
drop table TempData
select * into TempData from #TempTable
This helped me.
SELECT * FROM #Name
USE [TEMPDB]
GO
SELECT * FROM syscolumns
WHERE id = ( SELECT id FROM sysobjects WHERE [Name] LIKE '#Name%')
this gives the details of all the temp table