SQL SERVER

SQL Server Temp Table Mechanism: Complete Guide

intro

Let's explore everything you need to know about SQL Server temp table mechanisms to master the art of breaking complex tasks into smaller steps with temporary tables!

Tools used in the tutorial
Tool Description Link
Dbvisualizer DBVISUALIZER
TOP RATED DATABASE MANAGEMENT TOOL AND SQL CLIENT

In programming, it is common to store values in temporary data structures. In databases, the same concept is implemented through temporary tables, which are especially useful for simplifying complex procedures or SQL queries. SQL Server fully supports temporary tables, both local and global. Follow this guide to master the SQL Server temp table mechanism!

What Is an SQL Server Temporary Table?

In SQL Server, a temporary table is a special type of table that exists only for the duration of a session or until it is no longer needed. When a temp table goes out of scope, the database engine automatically drops it.

This mechanism is commonly used to store intermediate results, perform query optimization, or manipulate data without affecting permanent tables in the database.

In particular, SQL Server supports two types of temporary tables:

  • Local temporary tables: Visible only to the session that created them. They are automatically dropped when the session is closed. Their names are prefixed with a single number sign (#table_name).
  • Global temporary tables: Visible to all database sessions. They are removed once the session that created them ends and no other sessions are actively referencing them. Their names are prefixed with a double number sign (##table_name).

When and Why to Use SQL Server Temp Tables

The SQL Server temp table mechanism is ideal for handling intermediate data without impacting permanent tables. Specifically, temporary tables are useful in the following scenarios:

  • Breaking down multi-step queries for readability and performance.
  • Storing intermediate results during multi-step logic within stored procedures in SQL.
  • Cleaning or reshaping data before inserting it into permanent tables.
  • Holding data for branching logic (e.g., when using the SQL CASE statement) within scripts or procedures.
  • Avoiding repeated computation or SQL subqueries.
  • Storing result sets for short-lived operations, batches, etc.

In general, temporary tables in SQL Server are a powerful tool for performance tuning and modular query design.

How to Create a Temp Table in SQL Server

The syntax for creating a temporary table is nearly identical to the standard CREATE TABLE statement in SQL Server. The key difference is that the table name must be prefixed with either # or ##:

  • # is used for local temporary tables.
  • ## is used for global temporary tables.

For example, you can create a sample local temporary table with:

Copy
        
1 CREATE TABLE #MyLocalTempTable ( 2 Id INT PRIMARY KEY, 3 Name NVARCHAR(100) 4 );

This temp table is visible only within the current session and is automatically dropped when the session ends.

Similarly, you can define a global temporary table with:

Copy
        
1 CREATE TABLE ##MyGlobalTempTable ( 2 ID INT PRIMARY KEY, 3 Name NVARCHAR(100) 4 );

This temp table is accessible to all sessions and remains until all referencing sessions have ended.

For more, see our full guide on how to create temporary tables in SQL Server. Keep in mind that SQL Server temporary tables behave just like regular tables. You can perform all standard operations on them—such as SELECT, INSERT, UPDATE, and DELETE.

Notes:

  • The name of a local temporary table cannot exceed 116 characters. This limit allows SQL Server to append a unique internal suffix to distinguish between sessions. (You will learn more about this suffix shortly.)
  • Temporary tables do not support FOREIGN KEY constraints. Although you can include FOREIGN KEY definitions in the CREATE TABLE statement, SQL Server will ignore them and issue a warning. The table will still be created, but without the foreign key.
  • If a temporary table includes a named constraint (e.g., a named primary key or unique constraint) and is created within a user-defined transaction, only one user can execute the creation statement at a time. For instance, a stored procedure that defines a named constraint on a temp table cannot run concurrently across sessions.

How SQL Temporary Tables Work

SQL Server stores all temporary tables on disk in the tempdb system database. When you create a temp table in SQL Server, the database engine physically writes its structure and data to tempdb — similar to a regular table:

Exploring the SQL Server temp tables in tempdb with DbVisualizer
Exploring the SQL Server temp tables in tempdb with DbVisualizer

Local temporary tables are scoped to the current session or procedure, and are dropped when it ends. Global temporary tables remain until all sessions referencing them are closed.

Now, let's explore some specific scenarios to better understand how the SQL Server temp table mechanism works.

Creation in Triggers, Stored Procedures, and Modules

When a SQL Server local temporary table is created within a stored procedure or a SQL module that can be executed simultaneously by multiple sessions, the database engine must be able to distinguish between the tables created by each session.

To do that, the database engine automatically appends a unique suffix to each local temporary table name. As a result, the full name of the temporary table stored in the tempdb database consists of the table name specified in the CREATE TABLE statement, along with the system-generated suffix:

Note the appended suffix
Note the appended suffix

Note: The suffix is only visible internally, and you can still query a local temporary table without using its system-generated suffix.

A local temporary table created within a stored procedure or SQL trigger can share the same name as a temporary table created earlier. At the same time, if multiple temporary tables with the same name exist at the same time, it is undefined which table a query will reference.

In cases where nested stored procedures are involved, each procedure can create a temporary table with the same name as one created by a calling procedure. To ensure modifications are directed to the correct table in a nested procedure, the temporary tables must have identical structures, including matching column names.

Drop Conditions

SQL Server temporary tables are automatically dropped when they go out of scope, unless explicitly removed using DROP TABLE.

There are a couple of key aspects you need to keep in mind:

  1. Local temporary tables created inside a stored procedure are automatically dropped when the procedure completes. These tables can be accessed by any nested procedures called within that same procedure, but not by the parent process that invoked the procedure.
  2. All other local temporary tables are automatically dropped at the end of the session in which they were created.
  3. For global temporary tables, behavior depends on the GLOBAL_TEMPORARY_TABLE_AUTO_DROP database-scoped configuration. When set to ON (default), global SQL Server temp tables are automatically dropped when the creating session ends and no other active sessions are referencing the table. A session is considered to be referencing the table only during the execution of a Transact-SQL statement that uses it. This means the table is dropped at the end of the last statement actively using it, after the creating session ends. When set to OFF, global temporary tables persist until explicitly dropped using DROP TABLE, or until the SQL Server instance is restarted.

SQL Temp Table: Complete Example

Now that you know what SQL Server temporary tables are and how they work, let's see them in action with a real-world example.

Assume you want to retrieve a list of customers who have placed orders in the last 30 days, calculate the total order value for each customer, and filter those with a total order value greater than 500. The resulting query to achieve that goal can be quite complex:

Copy
        
1 SELECT c.CustomerID, c.CustomerName, SUM(o.OrderAmount) AS TotalOrderValue 2 FROM Customers c 3 JOIN Orders o ON c.CustomerID = o.CustomerID 4 WHERE o.OrderDate >= DATEADD(DAY, -30, GETDATE()) 5 GROUP BY c.CustomerID, c.CustomerName 6 HAVING SUM(o.OrderAmount) > 500 7 ORDER BY TotalOrderValue DESC;

As you can see, the query involves a GROUP BY, HAVING, ORDER BY, and aggregate functions, making it harder to follow.

If you execute this query in a SQL Server database client like DbVisualizer, you will get this result:

Executing the complex query in DbVisualizer
Executing the complex query in DbVisualizer

Time to simplify the complex query by using a SQL Server temp table!

Step #1: Create a Temp Table

Start by creating a local SQL Server temporary table that will store the aggregated order data:

Copy
        
1 CREATE TABLE #AggregatedOrders ( 2 CustomerID INT, 3 TotalOrderValue DECIMAL(10, 2) 4 );

As you can verify in DbVisualizer, the table was added to tempdb as expected:

Note the local temporary table under tempdb
Note the local temporary table under tempdb

Step #2: Populate the Temp Table

Next, populate the temporary table with the aggregated data:

Copy
        
1 INSERT INTO #AggregatedOrders (CustomerID, TotalOrderValue) 2 SELECT o.CustomerID, SUM(o.OrderAmount) AS TotalOrderValue 3 FROM Orders o 4 WHERE o.OrderDate >= DATEADD(DAY, -30, GETDATE()) 5 GROUP BY o.CustomerID 6 HAVING SUM(o.OrderAmount) > 500;

This should populate 3 rows as the original query selects 3 customers:

Note that DbVisualizer tells you that the rows affected were 3, as expected
Note that DbVisualizer tells you that the rows affected were 3, as expected

Step #3: Query the Temp Table

Now, you can query the temporary table with a simple JOIN query to get the results:

Copy
        
1 SELECT c.CustomerID, c.CustomerName, t.TotalOrderValue 2 FROM Customers c 3 JOIN #AggregatedOrders t ON c.CustomerID = t.CustomerID 4 ORDER BY t.TotalOrderValue DESC;

Launch the query within the same session and you will get:

Executing the SELECT query on the temp table
Executing the SELECT query on the temp table

Et voilà! The same result as before, but achieved through a simpler and more manageable approach using a temporary table.

Conclusion

In this article, you learned what SQL Server temporary tables are, how they work, when and why to use them, and how. You also saw a complete example to help you truly understand what benefits they bring to the table.

As shown here, working with SQL Server temp tables becomes much easier when using a powerful, feature-rich, multi-database client like DbVisualizer. This advanced tool also offers features like query optimization, SQL formatting, and schema visualization with ERD-like diagrams. Try DbVisualizer for free today!

FAQ

What is the naming convention for SQL Server temporary tables?

In SQL Server, temporary tables follow a specific naming convention:

  • Local temporary tables are prefixed with a single hash symbol (#), e.g., #LocalTempTable.
  • Global temporary tables are prefixed with double hash symbols (##), e.g., ##GlobalTempTable.

How do you select records into a temporary table in SQL Server?

To select records into a temporary table in SQL Server, you can use the SELECT INTO statement with a temp table name prefixed by # or ##. For example:

Copy
        
1 SELECT * INTO #TempEmployees 2 FROM Employees 3 WHERE Department = 'HR';

The above SQL Server SELECT INTO temporary table syntax creates the #TempEmployees table and inserts the result of the SELECT query into it. The table is stored in tempdb and behaves like a regular table for the duration of the session.

Do SQL Server temporary tables support indexes?

Yes, SQL Server temp tables support indexes. You can create both clustered and non-clustered indexes on them manually using the CREATE INDEX statement. This improves performance for large datasets or complex queries, just like with regular tables. Temporary tables in SQL Server also support primary keys and other constraints.

How do you drop a SQL Server temporary table if it exists?

In SQL Server 2016 or greater, the SQL Server drop temp table if exists syntax is:

Copy
        
1 DROP TABLE IF EXISTS #TempTable;

Where TempTable is the name of your local temp table. Otherwise, you can achieve the same result using the OBJECT_ID() function to check if the table exists before attempting to drop it:

Copy
        
1 IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL 2 DROP TABLE #TempTable;

This is a more general syntax to drop a temporary table if it exists in SQL Server.

Why use a visual database client to work with temporary tables in SQL Server?

Using a visual database client like DbVisualizer makes managing SQL Server temporary tables much easier. Since temp tables exist only within the scope of a session, it can be confusing to track them without proper visibility. Without a tool that fully supports SQL Server's features, you might not understand why a temp table disappears or where it is stored. This is just one of many advanced features DbVisualizer supports. Grab a 21-day trial to explore all its features!

Dbvis download link img
About the author
Antonello Zanini

Antonello is a software engineer, and often refers to himself as a technology bishop. His mission is to spread knowledge through writing.

The Table Icon
Sign up to receive The Table's roundup
More from the table
Title Author Tags Length Published
title

SQL Server CHARINDEX Function (Find Substring Position)

author TheTable tags SQL SERVER 6 min 2025-06-11
title

How to Compare Datetimes in SQL: Multiple Approaches

author TheTable tags MySQL ORACLE POSTGRESQL SQL SQL SERVER 5 min 2025-06-04
title

The Complete Guide to CONCAT in SQL Queries: Syntax, Examples, and Best Practices

author Leslie S. Gyamfi tags MySQL ORACLE POSTGRESQL SQL SQL SERVER 7 min 2025-06-03
title

How Often Should SQL Transaction Logs Be Backed Up?

author Antonello Zanini tags MySQL POSTGRESQL SQL SQL SERVER 7 min 2025-06-02
title

What Is a Database Catalog?

author Antonello Zanini tags MySQL ORACLE POSTGRESQL SQL SQL SERVER 6 min 2025-05-27
title

Check If A Table Exists in SQL: Multiple Approaches

author Antonello Zanini tags MySQL POSTGRESQL SQL SQL SERVER 6 min 2025-05-14
title

A Complete Guide to NOT EXISTS in SQL

author Antonello Zanini tags MySQL ORACLE POSTGRESQL SQL SQL SERVER 8 min 2025-05-12
title

SQL DROP TABLE IF EXISTS Statement: Complete Guide

author Antonello Zanini tags MySQL ORACLE POSTGRESQL SQL SQL SERVER 6 min 2025-05-05
title

TRUNCATE vs DELETE: SQL Comparison of the Two Statements

author Antonello Zanini tags MySQL ORACLE POSTGRESQL SQL SQL SERVER 9 min 2025-04-23
title

How to Extract the Year from a Date in SQL

author Antonello Zanini tags MySQL ORACLE POSTGRESQL SQL SQL SERVER 5 min 2025-04-21

The content provided on dbvis.com/thetable, including but not limited to code and examples, is intended for educational and informational purposes only. We do not make any warranties or representations of any kind. Read more here.