How to Find Source of Temp Tables - sql-server

In SSMS I see 7 temporary tables, all with names like dbo.#0876219E. When I end my connection and come back in, they are still there.
I'm not able to query them or get properties on them. I get errors.
How do I find their source, purpose and what they contain?
Is there a particular system sp that gives info on temp tables -- haven't been able to immediately find one.

Temp tables with such names (#, then 8 hex digits) are the temp tables that back table variables - declare #boris table (...)
They'll exist as long as the batch that introduced them continues to run. On my lightly loaded dev server, I can see ~30 of them, so I'm guessing there are some which are used/created by SQL Server itself - or possibly by SSMS.

Temp tables in SQL Server are perfectly normal. They are usually dropped when the database service is restarted (along with TempDB in which they are stored).
If you provide us with more context to where you see these temp tables, that would be helpful.
EDIT:
This quote is taken from the following forum post, which summarises the role of tempdb nicely:
tempdb is used for sorting,
aggregation, distincts, unions, temp
tables and table variables, row
versioning. It can also be used for
index building.
Oh and cursors

Related

Getting data of temp table while debugging

While debugging I am unable to watch temp table's value in sql server 2012.I am getting all of my variables value and even can print that but struggling with the temp tables .Is there any way to watch temp table's value?.
SQL Server provides the concept of temporary table which helps the developer in a great way. These tables can be created at runtime and can do the all kinds of operations that one normal table can do. But, based on the table types, the scope is limited. These tables are created inside tempdb database.
While debugging, you can pause the SP at some point, write the select statement in your SP before the DROP table statement, the # table is available for querying.
select * from #temp
I placed this code inside my stored procedure and I am able to see the temp table contents inside the "Locals" window.
INSERT INTO #temptable (columns) SELECT columns FROM sometable; -- populate your temp table
-- for debugging, comment in production
DECLARE #temptable XML = (SELECT * FROM #temptable FOR XML AUTO); -- now view #temptable in Locals window
This works on older SQL Server 2008 but newer versions would probably support a friendlier FOR JSON object. Credit: https://stackoverflow.com/a/6748570/1129926
I know this is old, I've been trying to make this work also where I can view temp table data as I debug my stored procedure. So far nothing works.
I've seen many links to methods on how to the do this, but ultimately they don't work the way a developer would want them to work. For example: suppose one has several processes in the Stored Procedure that updates and modifies data in the same temp table, there is no way to see update on the fly for each process in the SP.
This is a VERY common request, yet no one seems to have a solution other than don't use Stored Procedures for complex processing due how difficult they are to debug. If you're a .NET Core/EF 6 developer and have the correct PK,FK set for the database, one shouldn't really need to use Stored Procedures at all as it can all be handled by EF6 and debug code to view data results in your entities/models directly (usually in web API using models/entities).
Trying to retrieve the data from the tempdb is not possible even with the same connection (as has been suggested).
What is sometimes used is:
PRINT '#temptablename'
SELECT * FROM #temptablename
Dotted thruout the code, you can add a debug flag to the SP and selectively debug the output. NOT ideal at all, but works for many situations.
But this MUST already be in the Stored Procedure before execution (not during). And you must remember to remove the code prior to deployment to a production environment.
I'm surprised in 2022, we still have no solution to this other than don't use complex stored procedures or use .NET Core/EF 6 ... which in my humble opinion is the best approach for 2022 since SSMS and other tools like dbForge and RedGate can't accomplish this either.

I am struggling with migrating the temp tables (SQL server) to oracle

I am struggling with migrating the temp tables (SQL server) to oracle. Mostly, oracle don't consider to use temporary table inside the store procedure but in sql server, they are using temp tables for small fetching record and also manipulate same.
How to overcome this issue. I am also searching some online articles about migrating temp table to oracle but they are not clearly explained for my expectations.
i got information like using inline view, WITH clause, ref cursor instead of temp table. I am totally confused.
Please suggest me, in which case may use Inline view, WITH clause, ref cursor.
This may be helpful for improve my knowledge and also doing job well.
As always thank you for your valuable time in helping out the newbies.
Thanks
Alsatham hussain
Like many questions, the answer is "it depends". A few things
Oracle's "temp" table is called a GLOBAL TEMPORARY TABLE (GTT). Unlike most other vendor's TEMP tables, their definition is global. Scripts or programs in SQL Server (and others), will create a temp table and that temp table will disappear at the end of a session. This means that the script or program can be rerun or run concurrently by more than one user. However, this will not work with a GTT, since the GTT will remain in existence at the end of the session, so the next run that attempts to create the GTT will fail because it already exists.
So one approach is to pre-create the GTT, just like the rest of the application tables, and then change the program to INSERT into the gtt, rather than creating it.
As others have said, using a CTE Common Table Expression) could potentially work, buy it depends on the motivation for using the TEMP table in the first place. One of the advantages of the temp table is it provides a "checkpoint" in a series of steps, and allows for stats to be gathered on intermediate temporary data sets; it what is a complex set of processing. The CTE does not provided that benefit.
Others "intermediate" objects such as collections could also be used, but they have to be "managed" and do not really provide any of the advantages of being able to collect stats on them.
So as I said at the beginning, you choice of solution will depend somewhat on the motivation for the original temp table in the first place.

Run SSRS report based on temporary table

I am not sure if this is possible. I have an original data set that is approximately 1.5MM records. I want to do a number of things to this dataset in preparation to using it in a report with parameters. I am using SSRS and SQL Server 2008 R2.
What I was thinking of doing is creating a temp table #XYZ that would have a subset of the original 1.5MM records and would have the additional fields I need for reporting.
I can do all of that in a stored procedure. Can I use that temp table without copying it to a table in the db.
Just so you understand, two people may want to query the data at approximately the same time and I do not want to have conflicts with dropping or updating tables.
A temporary table is unique to a connection/session and gets dropped when the proc ends. If you run the same proc from two different windows in SSMS each connection gets its own temporary table, you won't have a problem...unless you use a global temporary table with two pound signs ##XYZ

Explicitly drop temp table or let SQL Server handle it

What is best practice for handling the dropping of a temp table. I have read that you should explicitly handle the drop and also that sql server should handle the drop....what is the correct method? I was always under the impression that you should do your own clean up of the temp tables you create in a sproc, etc. But, then I found other bits that suggest otherwise.
Any insight would be greatly appreciated. I am just concerned I am not following best practice with the temp tables I create.
Thanks,
S
My view is, first see if you really need a temp table - or - can you make do with a Common Table Expression (CTE). Second, I would always drop my temp tables. Sometimes you need to have a temp table scoped to the connection (e.g. ##temp), so if you run the query a second time, and you have explicit code to create the temp table, you'll get an error that says the table already exists. Cleaning up after yourself is ALWAYS a good software practice.
EDIT: 03-Nov-2021
Another alternative is a TABLE variable, which will fall out of scope once the query completes:
DECLARE #MyTable AS TABLE (
MyID INT,
MyText NVARCHAR(256)
)
INSERT INTO
#MyTable
VALUES
(1, 'One'),
(2, 'Two'),
(3, 'Three')
SELECT
*
FROM
#MyTable
CREATE TABLE (Transact-SQL)
Temporary tables are automatically dropped when they go out of scope, unless explicitly dropped by using DROP 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.
All other local temporary tables are dropped automatically at the end of the current session.
Global temporary tables are automatically dropped when the session that created the table ends and all other tasks have stopped referencing them. The association between a task and a table is maintained only for the life of a single Transact-SQL statement. This means that a global temporary table is dropped at the completion of the last Transact-SQL statement that was actively referencing the table when the creating session ended.
I used to fall into the crowd of letting the objects get cleaned up by background server processes, however, recently having issues with extreme TempDB log file growth has changed my opinion. I'm not sure if this has always been the case with every version of SQL Server, but since moving to SQL 2016 and putting the drives on a PureStorage SSD array, things run a bit differently. Processes are typically CPU bound rather than I/O bound, and explicitly dropping the temp objects results in no issues with log growth. While I haven't dug in too deeply as to why, I suspect it's not unlike garbage collection in the .NET world where it's synchronous when called explicitly and asynchronous when left to the system. This would matter because the explicit drop would release the storage in the log file, and make it available at the next log backup, whereas this appears to not be the case when not explicitly dropping the object. On most systems this is likely not a big issue, but on a system supporting a high volume ERP and web storefront with many concurrent transactions, and heavy TempDB use, it has had a big impact. As for why to create the TempDB objects in the first place, with the amount of data in most of the queries, it would spill over into TempDB storage anyway, so it's usually more efficient to create the object with the necessary indexes rather than let the system handle it automatically.
In a multi-threaded scenario where each thread creates its own set of tables and the number of threads is throttled, not dropping your own tables means that the governor will consider your thread done and spawn more threads... however the temp tables are still around (and thus the connections to the server) thus you'll exceed the limits of your governor. if you manually drop the temp tables then the thread doesn't finish until they've been dropped and no new threads are spawned, thus maintaining the governor's ability to keep from overwhelming the SQL engine
As per my view. No need to drop temp tables explicitly. SQL server will handle to drop temp tables stored in temp db in case of shorage of space to process query.

SQL Server Temp Tables and Connection Pooling

I have a multi-user ASP.NET app running against SQL Server and want to have StoredProcA create a #temptable temp table - not a table variable - to insert some data, then branch to StoredProcB, StoredProcC, and StoredProcD to manipulate the data in #temptable per business rules.
The web app uses connection pooling when talking to SQL. Will I get a new #temptable scratch area for each call of StoredProcA? Or will the connection pooling share the #temptable between users?
Connection pooling (with any modern version of SQL Server) will call sp_reset_connection when reusing a connection. This stored proc, among other things, drops any temporary tables that the connection owns.
A ## table will be shared by all users. I assume this is not your intention.
A single-# temp table is visible to all stored procedures down the call stack, but not visible outside that scope. If you can have Proc A call B, C, and D, you should be OK.
Edit: The reporting procedure I should be working on right now is a lot like that. :) I create a temp table (#results) in the root proc that's called by the application, then do some complicated data mangling in a series of child procedures, to 1) abstract repeated code, and 2) keep the root procedure from running to 500+ lines.
#temptable doesn't survive past the end of the procedure in which it was declared, so it won't ever be seen by other users.
Edit: Heh, it turns out that the "nesting visibility" of temp tables has worked since SQL Server 7.0, but I never updated any of my code to take advantage of this. I guess I'm dating myself -- a lot of people probably can't imagine the hell that was SQL Server in the 6.0 and 6.5 days...
From the MS docs:
http://msdn.microsoft.com/en-us/library/ms177399(SQL.90).aspx
Temporary Tables
Temporary tables are similar to permanent tables, except temporary tables are stored in tempdb and are deleted automatically when they are no longer used.
There are two types of temporary tables: local and global. They differ from each other in their names, their visibility, and their availability. Local temporary tables have a single number sign (#) as the first character of their names; they are visible only to the current connection for the user, and they are deleted when the user disconnects from the instance of SQL Server.
Global temporary tables have two number signs (##) as the first characters of their names; they are visible to any user after they are created, and they are deleted when all users referencing the table disconnect from the instance of SQL Server.
For example, if you create the table employees, the table can be used by any person who has the security permissions in the database to use it, until the table is deleted. If a database session creates the local temporary table #employees, only the session can work with the table, and it is deleted when the session disconnects. If you create the global temporary table ##employees, any user in the database can work with this table. If no other user works with this table after you create it, the table is deleted when you disconnect. If another user works with the table after you create it, SQL Server deletes it after you disconnect and after all other sessions are no longer actively using it.
Additionally from Curt who corrected the error of my ways and just in case you miss the citation in the comment:
http://msdn.microsoft.com/en-us/library/ms191132.aspx
If you create a local temporary
table inside a stored procedure, the
temporary table exists only for the
purposes of the stored procedure; it
disappears when you exit the stored
procedure.
If you execute a stored procedure
that calls another stored procedure,
the called stored procedure can
access all objects created by the
first stored procedure, including
temporary tables.
To share a temp table between users use two hashes before the name ##like_this.
In this case, though make sure you take steps to avoid clashes with multiple instances of the program.
Temp tables get created with name mangling under the hood so there shouldn't be conflicts between different stored procedure calls.
If you need to manipulate the same temp data in subsequent stored procedure calls, it's best to just go with a real table and use some sort of unique identifier to make sure you are only dealing with relevant data. If the data is only valuable temporarily, manually delete it once you're done.

Resources