How to fix Error 196 on Windows Server 2025 / Windows 11

Troubleshooting Guide: Error 196 – “SELECT INTO must be the first query in a statement containing a UNION”

Why This Error Happens

This error occurs because SQL Server’s T-SQL parser enforces a strict syntax rule: when using SELECT INTO to create a new table from a query, that SELECT INTO statement must appear as the very first query block within a UNION, UNION ALL, INTERSECT, or EXCEPT operation. This is not a permissions, port, or corruption issue—it is purely a query construction/syntax violation caused by placing INTO <table_name> in a subsequent SELECT within the combined statement, or by using it inside a subquery combined with set operators. The SQL Server 2025 query optimizer rejects the batch during the parsing/binding phase before execution ever begins, returning Error 196 immediately.

Step-by-Step Resolution Guide

Step 1: Identify the Offending Query Block

  • Open the query in SQL Server Management Studio (SSMS) 21 or Azure Data Studio and locate the exact SELECT INTO clause combined with UNION/UNION ALL.
  • Check whether the INTO clause is placed in the second, third, or later SELECT statement of the union rather than the first.
  • Use Ctrl+F to search for “INTO” within the batch to quickly find all instances.

Step 2: Reorder or Restructure the Statement

  • Move the SELECT INTO NewTable clause so it is the very first SELECT in the union chain.
  • Example fix:
  SELECT Col1, Col2 INTO NewTable FROM TableA
  UNION
  SELECT Col1, Col2 FROM TableB;
  • If restructuring isn’t logically possible, separate the operation into two steps: first create the table with CREATE TABLE or a single SELECT INTO, then use INSERT INTO ... SELECT with the UNION for subsequent rows.

Step 3: Refactor Using CREATE TABLE + INSERT (Recommended Pattern)

  • Replace the entire SELECT INTO ... UNION pattern with:
  CREATE TABLE NewTable (Col1 INT, Col2 VARCHAR(50));
  INSERT INTO NewTable (Col1, Col2)
  SELECT Col1, Col2 FROM TableA
  UNION
  SELECT Col1, Col2 FROM TableB;
  • This avoids the parser restriction entirely and gives you full control over column data types and constraints.

Step 4: Validate Syntax in a Test Environment

  • Run the corrected script against a non-production database or a tempdb copy first.
  • Confirm no other set operators (INTERSECT, EXCEPT) in the same batch are also violating the same rule.

Alternative or Verification Steps

  • Execute the corrected query in SSMS and confirm it returns “Command(s) completed successfully” instead of Error 196, then run SELECT * FROM NewTable; to verify row counts match expectations from both union branches.
  • If you cannot modify the original query (e.g., it’s in a third-party stored procedure), wrap the unioned SELECT statements in a Common Table Expression (CTE) or derived table, and apply SELECT ... INTO NewTable FROM (CTE/derived table) as a single outer statement instead.