I have a vb.net app , and I am creating and dropping temp tables. I just want to know whether the temp tables created programatically from some client app will get dropped automatically with dispose of application or we should have to drop it explicitly by code.
I need to be sure that all tables will get dropped when I close my app or that block has been executed successfully.
Right now I am dropping using drop table .... I need code to check existing temp table in sql server and drop them all at a time on form close.
I hope my lines are clear.
Environment is VB.Net + Sql Server 2008
Local Temp tables are disposed of when the session closes.
Global temp tables (with ## prefix) are dropped off when the last connection using it closes.
Related
I'm currently trying to determine possible issues with creating temporary tables from a web application and how SQL Server naturally determines separate sessions.
SELECT blabla, lala FROM table INTO #TempTable
SELECT blabla FROM #TempTable
DROP TABLE #TempTable
In the above, while one user of a web application is waiting for the second line to execute, and another user fires off the same 3 lines, what would determine whether the 2nd user gets a "Object already exists" or else a new #TempTable is created for that user.
If each user was on a separate computer on the same network, would SQL server treat this as separate sessions and thus create separate temporary tables.
What about if it is run on the same computer on two different networks?
Each user connection to the database is it own session. These sessions are unique even if you're using connection pooling within SQL Server. Behind the scenes, SQL Server appends each #tempTable with a single session reference number, so they technically aren't even named the same thing during execution.
If the root of your problem is an error message about the object already existing when you are debugging. Try adding the code snippet below before you create the temp table:
IF OBJECT_ID('[tempdb]..[#tempTable]') IS NOT NULL
BEGIN
DROP TABLE #tempTable
END
SQL Server does not determine separate sessions.
It is a client application who create sessions. You can write an application where all traffic to the database use single connection (not so easy) or a separate connection is created for each page (common mistake). Both of the solutions are pretty bad.
In proper design you should use connection pooling and your code should reserve connections from the connection pool as needed.
Even if you are using connection pooling, it is possible that each command is executed on a different connection from the pool.
I was wondering, what is the difference between these two scripts?
SELECT * FROM ##TEMP
and this
SELECT * FROM #TEMP
##TEMP is global temporary table, #TEMP is local.
Local temporary tables are visible only to their creators during the same connection to an instance of SQL Server as when the tables were first created or referenced. Local temporary tables are deleted after the user disconnects from the instance of SQL Server.
Global temporary tables are visible to any user and any connection after they are created, and are deleted when all users that are referencing the table disconnect from the instance of SQL Server.
see documentation.
Actually here is almost the same question with answer - Local and global temporary tables in SQL Server.
The first one (##TEMP) is global - anyone can access it's content and also you can from different sessions (think of tabs in SQL Server Management Studio). The other is only visible by you.
## are global tables which are visible to everyone and are deleted when all the connections that are referencing them are closed.
# are local tables that is visible to only the connection that has created it and are deleted once that connection has been disconnected.
After a user is logged into his system and opens my progamm he can see data from a database depending on his WindowsUsername(I wrote a little stored procedure for that).
This Data comes from a query with a temporary Table (#temp). My question is now, if many users use this programm, after opening it they would all try to build the #temp Table within the stored procedure. Is that even possible?? Because if i try to build a tempTable with the same name the server gives me an error. Do i have to give dynamic TempTable names maybe according to the user who is logged in??? Or is there another better option?
MS-SQL Server
A local temp table (one #TableName) is per session/connection
Many users can not share a session/connection
So, a local temp table in a stored procedure is safe for may concurrent users
On the other hand you use a global temp table (##TableName) then it is visible to world+dog
From MSDN (my bold)
There are two types of temporary tables: local and global. Local temporary tables are visible only to their creators during the same connection to an instance of SQL Server as when the tables were first created or referenced. Local temporary tables are deleted after the user disconnects from the instance of SQL Server. Global temporary tables are visible to any user and any connection after they are created, and are deleted when all users that are referencing the table disconnect from the instance of SQL Server.
If it is a true temp table within a stored procedure (SP) then the temp table is created/only exists during the execution of the SP. If the sp is run multiple times by multiple users at the same time the temp table is created multiple times and stored in its own memory space for each user.
The results returned to each user will be unique and each copy of the temp table will not see the temp table from other sp calls.
If you are testing in a query window by creating the temp table twice then you will get an error.
To prove that the above works schedule the SP to run twice at the same time passing a different user id. You will get two different result sets.
In SSMS can I select against temp tables created in the SPROC I'm debugging while the debugger is paused?
Something like in the immediate window of Visual Studio?
When I try SELECT in the command window, it doesn't work. IS this even possible?
From CREATE TABLE
Temporary Tables
You can create local and global
temporary tables. Local temporary
tables are visible only in the current
session; global temporary tables are
visible to all sessions.
You will notice from SSMS, that each tab has a different session id, so, I dont think this is possible, unless you make these global.
You can do the following:
Create the temp table, say #tmp1 outside of the stored procedure
Inside the stored procedure you can create the tmp table, if it doesn't exist. I'm not sure if that step is required.
Now after calling the stored procedure, you can select from the temp table.
Note:
I'm using this at work, but I'm not proud of this trick anymore. In a distributed development environment it is difficult to ensure, that both definitions of the temp table are identical. Maintenance can become a headache.
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.
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