5 Ways of Checking the Existence of Temporary Tables in SQL Server

When working with temporary tables in SQL Server, one of the most common tasks is checking whether the table already exists before creating it. This prevents errors in the event the table already exists, and ensures your scripts run smoothly regardless of previous executions.

In this article, we’ll explore five different approaches to checking for temporary table existence in SQL Server.

1. DROP TABLE IF EXISTS (SQL Server 2016+)

This is a great option for SQL Server 2016 and later versions. It only tries to drop the table if it already exists. If it doesn’t exist, then it won’t try to drop it and we won’t get an error.

Here’s an example:

DROP TABLE IF EXISTS #OrderTemp;

CREATE TABLE #OrderTemp (
    OrderID INT,
    OrderDate DATETIME,
    CustomerID INT,
    TotalAmount DECIMAL(12,2)
);

-- Insert sample data to verify the table was created
INSERT INTO #OrderTemp VALUES 
    (1, GETDATE(), 101, 299.99),
    (2, GETDATE(), 102, 159.50);

SELECT COUNT(*) AS RecordCount FROM #OrderTemp;

Output:

RecordCount
-----------
2

The DROP TABLE IF EXISTS syntax is atomic, meaning there’s no chance of race conditions between checking and dropping. It’s also the most concise and readable approach of all the options presented here.

2. OBJECT_ID() – The Best Option for Older SQL Server Versions

The OBJECT_ID() function returns the object identification number for a schema-scoped object, or NULL if the object doesn’t exist. This makes it perfect for existence checks and is the fastest method available in pre-2016 SQL Server versions. It’s also more reliable than querying system views because it’s optimized specifically for this purpose.

IF OBJECT_ID('tempdb..#MyTempTable') IS NOT NULL
    DROP TABLE #MyTempTable;

CREATE TABLE #MyTempTable (
    ID INT IDENTITY(1,1),
    Name VARCHAR(50),
    CreatedDate DATETIME DEFAULT GETDATE()
);

-- Insert some test data
INSERT INTO #MyTempTable (Name) VALUES ('Test 1'), ('Test 2');
SELECT * FROM #MyTempTable;

Output:

ID          Name                                               CreatedDate            
----------- -------------------------------------------------- -----------------------
1 Test 1 2025-07-30 09:20:41.677
2 Test 2 2025-07-30 09:20:41.677

The important part is specifying tempdb.. since all temporary tables are stored in the tempdb database, regardless of which database context you’re working in.

One benefit that this method has over DROP TABLE IF EXISTS is that we don’t necessarily need to drop the table. We can check OBJECT_ID() in order to do other stuff if we want. For example, we could use it to create the table only if it doesn’t exist – therefore preserving any existing data.

3. sys.tables System View – When You Need Additional Metadata

This method queries the system catalog directly, giving you more insight into SQL Server’s internal workings. In particular, it queries the tempdb.sys.tables system view.

This option can be useful when you need additional metadata about the table beyond just existence checking. The important thing to remember is that SQL Server appends random suffixes to temporary table names to ensure uniqueness across sessions, which is why we use the LIKE operator with wildcards.

IF EXISTS (
    SELECT 1 
    FROM tempdb.sys.tables 
    WHERE name LIKE '#CustomerTemp%'
)
    DROP TABLE #CustomerTemp;

CREATE TABLE #CustomerTemp (
    CustomerID INT,
    CustomerName VARCHAR(100),
    City VARCHAR(50)
);

-- Demonstrate the naming convention - temp tables get unique suffixes
SELECT name, object_id, create_date 
FROM tempdb.sys.tables 
WHERE name LIKE '#CustomerTemp%';

Output:

name                                                                                                                             object_id   create_date            
-------------------------------------------------------------------------------------------------------------------------------- ----------- -----------------------
#CustomerTemp_______________________________________________________________________________________________________00000000000C -1114606142 2025-07-30 09:23:20.177

This approach is more verbose than OBJECT_ID() but provides additional benefits when you need to retrieve metadata about the temporary table, such as creation date, object ID, or other system information. Use this method when you need more than just existence checking.

4. INFORMATION_SCHEMA Views – Standards-Based Approach

This method uses the ANSI standard INFORMATION_SCHEMA views, making it more portable across different database systems:

IF EXISTS (
    SELECT 1 
    FROM tempdb.INFORMATION_SCHEMA.TABLES 
    WHERE TABLE_NAME LIKE '#ProductTemp%'
    AND TABLE_TYPE = 'BASE TABLE'
)
    DROP TABLE #ProductTemp;

CREATE TABLE #ProductTemp (
    ProductID INT,
    ProductName VARCHAR(100),
    Price DECIMAL(10,2),
    CategoryID INT
);

-- Show table information using INFORMATION_SCHEMA
SELECT TABLE_NAME, TABLE_TYPE, TABLE_SCHEMA
FROM tempdb.INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE '#ProductTemp%';

Output:

TABLE_NAME                                                                                                                       TABLE_TYPE TABLE_SCHEMA                                                                                                                    
-------------------------------------------------------------------------------------------------------------------------------- ---------- --------------------------------------------------------------------------------------------------------------------------------
#ProductTemp________________________________________________________________________________________________________000000000003 BASE TABLE dbo

While this approach follows ANSI SQL standards and offers better portability, it’s generally slower than SQL Server-specific methods and still requires wildcard matching for temporary tables. Consider this method only if cross-database portability is a primary concern.

5. Exception Handling Approach – Generally Not Recommended

In some cases, a SQL developer might use exception handling to deal with table existence. While functional, it’s generally not recommended as it’s less efficient and harder to read than explicit existence checks. Exception handling should be reserved for actual error conditions, not normal control flow.

BEGIN TRY
    DROP TABLE #ErrorHandlingTemp;
END TRY
BEGIN CATCH
    -- Table didn't exist, which is fine
    PRINT 'Table did not exist, continuing...';
END CATCH

CREATE TABLE #ErrorHandlingTemp (
    ID INT,
    Message VARCHAR(100),
    Timestamp DATETIME DEFAULT GETDATE()
);

The following message is output the first time this is run:

Started executing query at Line 1
Table did not exist, continuing...
Total execution time: 00:00:00.011

Running it again produces the usual “completed successfully” message:

Started executing query at Line 1
Commands completed successfully.
Total execution time: 00:00:00.016

Using exceptions for control flow is not normally a good idea because it’s less efficient than explicit checks, makes code harder to maintain and debug, and can mask real errors. You should only consider this approach in very specific scenarios where other methods aren’t suitable.

Summary

Here’s a quick recap:

  1. For SQL Server 2016 and later: Use DROP TABLE IF EXISTS – it’s the most modern, atomic, and readable approach.
  2. For SQL Server 2014 and earlier: Use OBJECT_ID('tempdb..#TableName') IS NOT NULL for maximum performance and reliability.
  3. When you need metadata: Use sys.tables queries only when you need additional information about the temporary table beyond just existence checking.
  4. For portability concerns: Use INFORMATION_SCHEMA views only if cross-database portability is a primary requirement, accepting the performance trade-off.
  5. Avoid exception handling: Never use try/catch blocks for routine existence checks – reserve them for actual error conditions.