首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 跨資料表資料複製:INSERT INTO SELECT 語法詳解與實務範例

     編輯:關於SqlServer

前言

在 SQL Server 中,將某資料表的資料複製到另一張結構相同或相容的資料表,最標準、效能最佳的做法是使用 INSERT INTO ... SELECT 陳述式。本文說明語法細節、欄位對應原則、條件過濾與常見陷阱。

一、基本語法架構

INSERT INTO 目標資料表 (欄位1, 欄位2, ...)
SELECT 欄位1, 欄位2, ...
FROM 來源資料表
[WHERE 條件];

關鍵規則

  • 欄位清單須一一對應:目標欄位清單與 SELECT 清單的順序、數量、資料型別必須相容。
  • 可省略目標欄位清單:若目標表結構與 SELECT 結果完全一致 (含順序),可寫 INSERT INTO 目標表 SELECT ...,但不建議,易因結構變更導致錯誤。
  • 識別碼欄位 (IDENTITY):若目標表有身分識別欄位,預設不可指定值;需 SET IDENTITY_INSERT 目標表 ON 後方可插入指定值,完成後記得 OFF。
  • 觸發器與條件約束:複製過程會觸發目標表的 INSERT 觸發器,並檢查 FK、CHECK、DEFAULT 等約束。

二、完整實務範例

範例 1:完整複製 (含所有欄位)

INSERT INTO www_templet (
    tid, name, templet, content, content1, url, url1, [time], [admin], qx, city, isoverWrite, isGlobal
)
SELECT
    tid, name, templet, content, content1, url, url1, [time], [admin], qx, city, isoverWrite, isGlobal
FROM [Dichan_News].[dbo].[Sheet1$];
  • 來源為連結伺服器/異質資料來源 (Excel/Access) 時,使用四部分命名 [LinkedServer].[DB].[Schema].[Table]。
  • 欄位名含保留字或空白時,用 [] 或 "" (QUOTED_IDENTIFIER ON) 括住。

範例 2:條件過濾複製

INSERT INTO Archive_Orders (OrderID, CustomerID, OrderDate, TotalAmount)
SELECT OrderID, CustomerID, OrderDate, TotalAmount
FROM dbo.Orders
WHERE OrderDate < '2023-01-01' AND Status = 'Completed';

範例 3:跨資料庫/跨伺服器複製

-- 同一實例不同資料庫
INSERT INTO DB_B.dbo.TargetTable (col1, col2)
SELECT col1, col2 FROM DB_A.dbo.SourceTable;

-- 連結伺服器
INSERT INTO LocalDB.dbo.TargetTable (col1, col2)
SELECT col1, col2 FROM [LinkedSrv].RemoteDB.dbo.SourceTable;

三、效能優化建議

技巧 說明
最小化記錄 SQL 2008+ 使用 WITH (TABLOCK) 於目標表 + 簡單復原模式/大量記錄模式,可達最小記錄 (Minimal Logging),大幅減少記錄檔增長與 I/O。
分批次處理大量資料 避免單一交易過大導致記錄檔暴增、鎖定升級、封鎖。建議每批 5,000–50,000 筆,搭配 TOP + WHILE 迴圈。
預先停用非叢集索引 大量插入前 DISABLE 非叢集索引,完成後 REBUILD,避免逐筆維護索引開銷。
排序輸入資料 若目標表有叢集索引,依叢集鍵順序 SELECT 可減少頁分裂與碎片。

四、常見錯誤與排解

錯誤訊息 原因 解決
Column name or number of supplied values does not match table definition. 欄位數量/順序不符 明確列出目標欄位清單,確保與 SELECT 清單一致
Cannot insert explicit value for identity column... 嘗試插入 IDENTITY 欄位值 SET IDENTITY_INSERT Table ON / 移除 SELECT 中的身分識別欄位
The SELECT permission was denied... 來源表無 SELECT 權限 授予 GRANT SELECT ON SourceTable TO User
String or binary data would be truncated. 來源資料長度超過目標欄位定義 檢查資料長度、調整目標欄位長度、或用 LEFT/SUBSTRING 截斷

五、進階:MERGE 替代方案 (Upsert 需求)

若需「存在則更新、不存在則插入」:

MERGE INTO TargetTable AS T
USING SourceTable AS S ON T.PK = S.PK
WHEN MATCHED THEN UPDATE SET T.col1 = S.col1, T.col2 = S.col2
WHEN NOT MATCHED THEN INSERT (PK, col1, col2) VALUES (S.PK, S.col1, S.col2);

適用於資料同步、ETL 增量載入等場景。

結語

INSERT INTO ... SELECT 是 SQL Server 複製資料的基石指令。掌握欄位對應、條件過濾、跨資料庫存取、最小記錄與分批次技巧,能安全高效完成從簡單備份歸檔到大規模 ETL 載入的各類需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved