SELECT [column_list] INTO [new_table] FROM [source] WHERE [condition];
new_table 結構完全基於 SELECT 列表的數據類型、可空性、Identity 屬性 (僅當單一 Identity 列且無表達式)。DEFAULT 文件組)。WHERE 1=0 / WHERE 0=1 → 零行複製,僅獲取空表結構。SELECT INTO/bulkcopy = ON (簡單恢復模式下默認 ON,完整恢復模式需開啟)。
-- 方法:創建聚簇索引時指定文件組 (SELECT INTO 不直接支持)
SELECT * INTO TargetTable ON [FG_Data] FROM SourceTable WHERE 1=0; -- ❌ 語法錯誤
-- 正確模式:SELECT INTO 默認文件組 → 立即創建聚簇索引移動數據 (此處無數據,僅結構)
SELECT * INTO TargetTable FROM SourceTable WHERE 1=0;
CREATE CLUSTERED INDEX CX_TargetTable ON TargetTable (Id) ON [FG_Data]; -- 移動到目標 FG
-- 或預先創建表結構 (含 ON FG) 再 INSERT SELECT
-- 源表為分區表,SELECT INTO 創建的表默認非分區
SELECT * INTO TargetTable FROM PartitionedSource WHERE 1=0;
-- 後續需手動創建分區函數/方案/索引對齊分區
SELECT
Id,
FirstName + ' ' + LastName AS FullName, -- 計算列 (非持久化)
CAST(Price * 1.1 AS DECIMAL(10,2)) AS PriceWithTax,
CASE WHEN Status = 1 THEN 'Active' ELSE 'Inactive' END AS StatusDesc
INTO NewTable
FROM SourceTable
WHERE 1=0;
-- 新表列類型為表達式結果類型,計算列不持久化。需持久化請用 CREATE TABLE + PERSISTED。
SELECT INTO 為最小日誌操作:僅記錄頁分配、不記錄行級插入,速度極快,適合大表複製/歸檔。ALTER DATABASE DB SET RECOVERY SIMPLE; SELECT INTO ...; ALTER DATABASE DB SET RECOVERY FULL; BACKUP LOG ...。#Temp vs SELECT INTO #Temp
-- 兩者等價,但 SELECT INTO 更靈活 (無需預先定義列)
SELECT * INTO #Tmp FROM Source WHERE Cond;
-- 避免在長事務中使用 SELECT INTO #Temp (鎖系統表 sysobjects/syscolumns 導致阻塞),短事務無妨。
SELECT INTO vs CREATE TABLE + INSERT SELECT| 維度 | SELECT INTO | CREATE TABLE + INSERT |
|---|---|---|
| DDL 鎖 | 創建表時鎖系統表 (Sch-M),大表結構鎖時間長 | 創建表鎖系統表,INSERT 只鎖用戶表 |
| 日誌量 | 最小日誌 (簡單/大量日誌模式) | 全日誌 (每行記錄) |
| 並發影響 | DDL 阶段阻塞其他建表/修改架構操作 | INSERT 可分批提交,長事務可控 |
| 結構控制 | 自動推導,不可指定約束/索引/壓縮/FG | 完全控制:PK、FK、CHECK、DEFAULT、INDEX、COMPRESSION、FG |
| 適用場景 | 臨時探索、大表歸檔、結構同步腳本生成 | 生產建表、ETL 目標表、需完整約束的場景 |
-- 動態生成 SELECT INTO 腳本,用於跨環境同步表結構 (僅結構)
DECLARE @Sql NVARCHAR(MAX) = N'';
SELECT @Sql += N'SELECT * INTO ' + QUOTENAME(SCHEMA_NAME(schema_id)) + '.' + QUOTENAME(name)
+ N' FROM ' + QUOTENAME(SCHEMA_NAME(schema_id)) + '.' + QUOTENAME(name) + N' WHERE 1=0;'
FROM sys.tables
WHERE is_ms_shipped = 0
AND name IN ('Orders','Customers','Products'); -- 目標表列表
PRINT @Sql; -- 複製到目標環境執行
SELECT INTO 是「結構推導 + 最小日誌複製」的瑞士軍刀。**善用 WHERE 1=0 獲取空結構、理解最小日誌條件、補齊索引約束、配合動態 SQL 實現跨環境結構同步**,能大幅提升 DBA 開發運維效率。切記:生產核心表建表仍以 CREATE TABLE 完整定義為準,SELECT INTO 歸屬探索/歸檔/工具類場景。