原始語法

INSERT INTO [_kiin_].[dbo].[T_B1A](料號)
SELECT A.料號
FROM OPENQUERY([192.168.88.243],'
SELECT 料號
FROM [_kiin_].[dbo].[T_B1A]
'
) AS A
LEFT JOIN [_kiin_].[dbo].[vQ_B1A_B] AS B
ON B.料號 = A.料號
WHERE B.料號 IS NULL;

第 1 行

INSERT INTO [_kiin_].[dbo].[T_B1A](料號)

👉 指定 本機 要新增資料的資料表
👉 只新增「料號」這個欄位

第 2~7 行(最關鍵)

FROM OPENQUERY([192.168.88.243],'
SELECT 料號
FROM [_kiin_].[dbo].[T_B1A]
'
) AS A

這行是效能的靈魂

意思是:

這段 SQL 不是在本機跑
是送到 192.168.88.243 那台 SQL Server 自己執行

遠端實際執行的是:

SELECT 料號
FROM [_kiin_].[dbo].[T_B1A]

然後只把 結果(只有料號) 傳回來。

為什麼這非常重要?

如果你不用 OPENQUERY,而是:

FROM [192.168.88.243].[_kiin_].[dbo].[T_B1A]

SQL Server 會:

把遠端整張表很多欄位抓回來 → 本機再篩選

但 OPENQUERY 是:

遠端先篩好 → 只傳必要資料回來

差距非常大。

第 8~10 行

LEFT JOIN [_kiin_].[dbo].[vQ_B1A_B] AS B
ON B.料號 = A.料號

這是在本機做的事:

用遠端傳回來的料號 (A)
去比對本機 vQ_B1A_B 有沒有這個料號

LEFT JOIN 的意思是:

遠端有 本機有 結果
B.料號 有值
B.料號 = NULL ← 我們要的

第 11 行(精華)

WHERE B.料號 IS NULL;

意思是:

遠端有這個料號
但本機沒有

這正是你要新增的資料。

SQL Server 實際執行流程(非常重要)

  1. 遠端 88.243 自己跑:

    SELECT 料號 FROM T_B1A
  2. 只把「料號清單」傳回本機

  3. 本機把 vQ_B1A_B 做 Hash Table

  4. 一次比對所有料號

  5. 找出不存在的

  6. INSERT

沒有一筆一筆查,這就是為什麼它會非常快。


和你原本 NOT EXISTS 差在哪?

原本是:

for each 遠端料號
去本機查一次

現在是:

本機先準備好比對表
一次掃描遠端結果

等級完全不同。


一句話總結這段 SQL 的意思

「請 88.243 自己把料號準備好傳來,我只負責判斷我這裡有沒有,沒有就加進來。」

這就是 Linked Server 正確使用方式


這段可以套用在你所有同步程式

只要邏輯是:

遠端有,本機沒有 → 新增

全部都可以套這個模板

個人頭像照片

By 伍 芳左

MIS, ERP Pro...

發佈留言