[SQL]MERGE 陳述式與OUTPUT
上課有教到練習一下,需要sql server 2008之後的版本才有支援。
問題描述
員工備份檔的資料過於老舊,需要更新。
目的
比對員工檔與員工備份檔的內容,並且修改員工備份檔內容為員工檔。
表格定義
員工檔(EMPLOYEE_PARTIAL)
員工檔(EMPLOYEE_OLD_PARTIAL)
執行SQL
--Output And Merge
USE EMPDATA
GO
-- 設定初始資料
IF exists
(SELECT name
FROM
sys.tables
WHERE
name = 'EMPLOYEE_OLD_PARTIAL') DROP TABLE dbo.EMPLOYEE_OLD_PARTIAL
GO
SELECT STAFF
, BRNO
INTO
dbo.EMPLOYEE_OLD_PARTIAL
FROM
dbo.EMPLOYEE_OLD
GO
IF exists
(SELECT name
FROM
sys.tables
WHERE
name = 'EMPLOYEE_PARTIAL') DROP TABLE dbo.EMPLOYEE_PARTIAL
GO
SELECT STAFF
, BRNO
INTO
dbo.EMPLOYEE_PARTIAL
FROM
dbo.EMPLOYEE
GO
-- 檢查資料是否建立完畢
SELECT *
FROM
dbo.EMPLOYEE_OLD_PARTIAL
SELECT *
FROM
dbo.EMPLOYEE_PARTIAL
GO
-- 比較EMPLOYEE_PARTIAL與EMPLOYEE_OLD_PARTIAL
-- 判斷規則如下
/* 1. 如果現行人員單位代號不一樣
update EMPLOYEE_OLD_PARTIAL.BRNO = EMPLOYEE_PARTIAL.BRNO
2. 如果EMPLOYEE_OLD_PARTIAL沒有人員資料(新員工)
insert record to EMPLOYEE_OLD_PARTIAL
2. 如果EMPLOYEE_PARTIAL沒有人員資料(離職員工)
delete record from EMPLOYEE_OLD_PARTIAL
*/
DECLARE @differMatch table
(
MYACTION varchar(20),
BEFORE_STAFF nvarchar(6),
BEFORE_BRNO nvarchar(4),
AFTER_STAFF nvarchar(6),
AFTER_BRNO nvarchar(4)
);
MERGE dbo.EMPLOYEE_OLD_PARTIAL AS d
USING (
SELECT [STAFF]
, [BRNO]
FROM
[dbo].[EMPLOYEE_PARTIAL]) AS s
ON s.STAFF=d.STAFF and s.BRNO <> d.BRNO
WHEN MATCHED THEN
UPDATE
SET d.BRNO = s.BRNO
WHEN NOT MATCHED and not exists(select STAFF from EMPLOYEE_OLD_PARTIAL where STAFF=s.STAFF)
THEN
INSERT (STAFF,BRNO)VALUES(s.STAFF,s.BRNO)
WHEN NOT MATCHED BY SOURCE and not exists(select STAFF from EMPLOYEE_PARTIAL where STAFF=d.STAFF)
THEN
DELETE
OUTPUT $action,Inserted.*, Deleted.* into @differMatch;
SELECT *
FROM
@differMatch
GO
-- 檢查資料是否一致
SELECT *
FROM
dbo.EMPLOYEE_OLD_PARTIAL
EXCEPT
SELECT *
FROM
dbo.EMPLOYEE_PARTIAL
go
SELECT *
FROM
dbo.EMPLOYEE_PARTIAL
EXCEPT
SELECT *
FROM
dbo.EMPLOYEE_OLD_PARTIAL
go
結果畫面
資料變更狀態(insert、update或delete)可由SSMS得知