Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Gunakan Kasus untuk Pernyataan MERGE SQL Server:Menyinkronkan Tabel Online dan Riwayat

PENGANTAR

Pernyataan SQL Server MERGE adalah alat yang sangat berguna untuk menjalankan operasi DML berdasarkan perbandingan dua tabel atau dua kumpulan data. Penggunaan pernyataan ini sebenarnya seperti melakukan beberapa operasi dalam satu pernyataan.

Artikel ini akan mengeksplorasi tiga kasus penggunaan yang membatasi untuk memastikan data antara tabel online dan tabel riwayat sinkron.

Mari kita jelaskan skenario dalam beberapa pernyataan yang diuraikan yang akan familiar bagi banyak DBA atau pengembang:

  1. Tabel sumber bernama Trans merekam transaksi yang terjadi secara real-time secara berkelanjutan.
  2. Periode retensi yang disepakati untuk table Tran adalah satu bulan. Trans harus dibersihkan setiap akhir bulan.
  3. Setiap hari, data Tran harus dikirim ke TranHistory selama proses “Akhir Hari”.
  4. Sejarah Trans tabel adalah tabel historis yang menggabungkan data transaksi selama satu tahun.
  5. Semua sisipan dan pembaruan pada Trans tabel harus tercermin dalam TranHistory meja di akhir setiap hari.

MENYIAPKAN SKENARIO

Skenario yang dijelaskan di atas menyiratkan bahwa catatan di tabel Tran juga ada di tabel TranHistory hingga dihapus setiap bulan. Setiap hari, akan ada beberapa catatan baru di tabel Tran tetapi BUKAN di tabel TranHistory. Kita harus menemukan cara untuk menyisipkan baris baru ini.

Pertama, mari kita siapkan tabel yang dimaksud (Lihat Daftar 1 dan 2).

-- Listing 1: Create Tran Table
USE AU
GO
CREATE TABLE [Tran] (
  responseId int NOT NULL ,
  senderId varchar(15) ,
  msisdn varchar(15) ,
  [message] varbinary ,
  status smallint ,
  application varchar ,
  receivedTime timestamp NULL ,
  processedTime datetime2 NULL ,
  flag smallint ,
  requestDelivery smallint ,
  delivered smallint ,
  account varchar(20) ,
  srcTon smallint ,
  srcNpi smallint ,
  destTon smallint ,
  destNpi smallint ,
  errorCode smallint ,
  messageId varchar ,
  sequenceNo int ,
  retries smallint ,
  messagePriority int ,
  userId varchar(20) ,
  bulkId varchar(20) 
)
-- Listing 2: Create TranHistory Table
USE AU
GO
CREATE TABLE [TranHistory] (
  responseId int NOT NULL ,
  senderId varchar(15) ,
  msisdn varchar(15) ,
  [message] varchar(160) ,
  status smallint ,
  application varchar ,
  receivedTime datetime2 NULL ,
  processedTime datetime2 NULL ,
  flag smallint ,
  requestDelivery smallint ,
  delivered smallint ,
  account varchar(20) ,
  srcTon smallint ,
  srcNpi smallint ,
  destTon smallint ,
  destNpi smallint ,
  errorCode smallint ,
  messageId varchar ,
  sequenceNo int ,
  retries smallint ,
  messagePriority int ,
  userId varchar(20) ,
  bulkId varchar(20) ,
  archivedTime datetime2 NOT NULL ,
)

Bila TIDAK COCOK MAKA MASUKKAN

Menggunakan kode di Listing 3, kami menyisipkan beberapa baris di tabel Tran untuk memulai. Kemudian, kami melanjutkan menggunakan pernyataan MERGE untuk memindahkan data ke tabel TranHistory.

-- Listing 3: Insert Initial Set of Rows in Tran Table
USE [AU]
GO

INSERT INTO [dbo].[Tran]
     VALUES
           (8000,'0233456789','Wishing you a Happy New Year',1,'K','20201110 15:00:00','20201110 15:10:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(7777,'0233456789','The blessing of the Lord be with you',1,'K','20201110 08:00:00','20201110 08:10:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(7005,'0234876789','Happy Birthday to you',1,'K','20201110 09:00:00','20201110 09:20:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(9002,'0233456789','Merry Christmas',1,'K','20201110 07:00:00','20201110 07:15:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(6789,'0233467889','Buy our brand new cars for less than $8000',1,'K','20201110 14:00:00','20201110 14:20:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(7685,'0244556789','Happy New Month. God bless and increase you',1,'K','20201110 17:00:00','20201110 17:08:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(4983,'0229856789','Help is coming your way today!',1,'K','20201110 19:00:00','20201110 19:20:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(6879,'0239986789','Call us for your next relocation project',1,'K','20201110 19:15:00','20201110 19:20:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(4567,'0233456789','Hard Work Always Pays',1,'K','20201110 22:05:00','20201110 22:20:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(8890,'0244656733','Don''t wait to buy land, buy land and wait',1,'K','20201110 15:05:00','20201110 15:20:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(6789,'0233466734','We are relocating. Call us on 077788997',1,'K','20201110 18:02:00','20201110 18:17:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(9899,'0233456556','Watch out for our latest movie',1,'K','20201110 06:00:00','20201110 06:02:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(6789,'0233456338','We are here to make you happy',1,'K','20201110 12:16:00','20201110 12:20:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
GO

Kita dapat melakukannya dengan cara yang lebih sederhana, tetapi kita ingin menunjukkan sintaks pernyataan MERGE (Lihat Daftar 4):

-- Listing 4: Merge Records in Tran Table to TranHistory Table
MERGE INTO [TranHistory] a USING [Tran] b
ON a.responseId=b.responseID
WHEN NOT MATCHED BY TARGET THEN INSERT
([responseId],[senderId],[msisdn],[message],[status],[application],[receivedTime],[processedTime],[flag],[requestDelivery],[delivered],[account],[srcTon],[srcNpi],[destTon],[destNpi],[errorCode],[messageId],[sequenceNo],[retries],[messagePriority],[userId],[bulkId],[archivedTime])
 VALUES 
([responseId],[senderId],[msisdn],[message],[status],[application],[receivedTime],[processedTime],[flag],[requestDelivery],[delivered],[account],[srcTon],[srcNpi],[destTon],[destNpi],[errorCode],[messageId],[sequenceNo],[retries],[messagePriority],[userId],[bulkId],getdate());
GO

Pernyataan MERGE mengatakan:

  1. Ambil isi tabel [Tran] dan bandingkan dengan tabel [TranHistory] berdasarkan responseId kolom.
  2. Sisipkan baris yang Anda temukan di tabel sumber tetapi tidak ditemukan di tabel target (TranHistory).

Karena itu, Tran dan TranHistory cocok. Tapi misalkan keesokan harinya, baris baru diperkenalkan di Tabel Trans. Kita juga harus mendorongnya ke tabel TransHistory sambil menyimpan catatan di tabel Tran hingga bulan berakhir.

Kami kembali menggunakan skrip dalam daftar 4. Kali ini, kami menambahkan klausa OUTPUT untuk memberi tahu apa yang diperkenalkan (Lihat Daftar 5):

-- Listing 5: Merge Records in Tran Table to TranHistory Table (Add OUTPUT Clause)
USE AU
GO

MERGE INTO [TranHistory] a USING [Tran] b
ON a.responseId=b.responseID
WHEN NOT MATCHED BY TARGET THEN INSERT
([responseId],[senderId],[msisdn],[message],[status],[application],[receivedTime],[processedTime],[flag],[requestDelivery],[delivered],[account],[srcTon],[srcNpi],[destTon],[destNpi],[errorCode],[messageId],[sequenceNo],[retries],[messagePriority],[userId],[bulkId],[archivedTime])
 VALUES 
([responseId],[senderId],[msisdn],[message],[status],[application],[receivedTime],[processedTime],[flag],[requestDelivery],[delivered],[account],[srcTon],[srcNpi],[destTon],[destNpi],[errorCode],[messageId],[sequenceNo],[retries],[messagePriority],[userId],[bulkId],getdate())
OUTPUT deleted.*, $action, inserted.*;
GO

Kami dapat mengulangi proses ini setelah memasukkan baris tambahan ke tabel Tran (Daftar 6 dan 7), dan kami mendapatkan perilaku serupa:

-- Listing 6: Insert Six New Rows in Tran Table
USE [AU]
GO

INSERT INTO [dbo].[Tran]
     VALUES
			(6879,'0239986789','Call us for your next relocation project',1,'K','20201110 19:15:00','20201110 19:20:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(4567,'0233456789','Hard Work Always Pays',1,'K','20201110 22:05:00','20201110 22:20:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(8890,'0244656733','Don''t wait to buy land, buy land and wait',1,'K','20201110 15:05:00','20201110 15:20:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(6789,'0233466734','We are relocating. Call us on 077788997',1,'K','20201110 18:02:00','20201110 18:17:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(9899,'0233456556','Watch out for our latest movie',1,'K','20201110 06:00:00','20201110 06:02:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(6789,'0233456338','We are here to make you happy',1,'K','20201110 12:16:00','20201110 12:20:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
GO
-- Listing 7: Insert Additional Three Rows in Tran Table
USE [AU]
GO

INSERT INTO [dbo].[Tran]
     VALUES
	(7789,'0233456433','Are you ready for your next level?',1,'K','20201110 14:35:00','20201110 14:40:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(8000,'0233457759','Hutchies Honey, another level of taste',1,'K','20201110 08:00:00','20201110 08:08:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(7777,'0233458909','Make sure you vote tomorrow',1,'K','20201110 09:45:00','20201110 09:50:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
			,(9890,'0233459994','Wishing you a Merry Christmas',1,'K','20201110 10:00:00','20201110 10:05:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
GO

KETIKA COCOK MAKA UPDATE

Kasus lain adalah pembaruan ke tabel langsung (Tran) ketika kami ingin menyinkronkan pembaruan tersebut ke tabel TranHistory. Kami membuat skenario ini dengan memperbarui baris di tabel Tran menggunakan skrip di Listing 8.

-- Listing 8: Update and Insert Rows in Tran Table
USE AU
GO

UPDATE [dbo].[Tran] SET account='JUNIPER' 
WHERE account='KAIROS';
GO

INSERT INTO [dbo].[Tran]
     VALUES
	(5578,'0233566933','Newest on the Block!',1,'K','20201110 14:35:00','20201110 14:40:00',1,1,1,'KAIROS',1,2,3,4,1,1,9789,2,1,'ROUTEMOBILE','9988776')
GO

Gambar 6 menunjukkan bahwa baris diperbarui dalam tabel tujuan. Kami mendapatkan detail ini menggunakan klausa OUTPUT.

Kita harus menggunakan klausa yang disorot dalam Daftar 9. Pernyataan MERGE mengidentifikasi baris yang cocok dengan kondisi GABUNG dan memperbarui data di kolom yang ditentukan (akun ). Kami dapat memperbarui beberapa baris dengan pendekatan ini.

-- Listing 9: Sync Data in TranHistory by Updating Rows
USE AU
GO

MERGE INTO [TranHistory] a USING [Tran] b
ON a.responseId=b.responseID
WHEN MATCHED THEN UPDATE
SET a.account=b.account
WHEN NOT MATCHED BY TARGET THEN INSERT
([responseId],[senderId],[msisdn],[message],[status],[application],[receivedTime],[processedTime],[flag],[requestDelivery],[delivered],[account],[srcTon],[srcNpi],[destTon],[destNpi],[errorCode],[messageId],[sequenceNo],[retries],[messagePriority],[userId],[bulkId],[archivedTime])
 VALUES 
([responseId],[senderId],[msisdn],[message],[status],[application],[receivedTime],[processedTime],[flag],[requestDelivery],[delivered],[account],[srcTon],[srcNpi],[destTon],[destNpi],[errorCode],[messageId],[sequenceNo],[retries],[messagePriority],[userId],[bulkId],getdate())
OUTPUT deleted.*, $action, inserted.*;
GO

APABILA TIDAK COCOK DENGAN SUMBER LALU HAPUS

Satu skenario lagi melibatkan baris yang dihapus dari tabel sumber (Daftar 10). Ketika itu terjadi, kita harus mengidentifikasi baris yang tidak lagi ada di tabel sumber dan menghapusnya dari tabel tujuan.

Kami melakukannya dengan menggunakan klausa yang disorot dalam Daftar 10. Sekali lagi, Gambar 7 dan 8 menunjukkan baris yang dipengaruhi oleh pernyataan MERGE ini.

-- Listing 10: Update and Insert Rows in Tran Table
USE AU
GO

DELETE FROM [dbo].[Tran] 
WHERE account='JUNIPER';
GO
-- Listing 11: Syncing Tables After Deleting from Tran Table
USE AU
GO

MERGE INTO [TranHistory] a USING [Tran] b
ON a.responseId=b.responseID
WHEN NOT MATCHED BY SOURCE THEN DELETE
WHEN MATCHED THEN UPDATE
SET a.account=b.account
WHEN NOT MATCHED BY TARGET THEN INSERT
([responseId],[senderId],[msisdn],[message],[status],[application],[receivedTime],[processedTime],[flag],[requestDelivery],[delivered],[account],[srcTon],[srcNpi],[destTon],[destNpi],[errorCode],[messageId],[sequenceNo],[retries],[messagePriority],[userId],[bulkId],[archivedTime])
 VALUES 
([responseId],[senderId],[msisdn],[message],[status],[application],[receivedTime],[processedTime],[flag],[requestDelivery],[delivered],[account],[srcTon],[srcNpi],[destTon],[destNpi],[errorCode],[messageId],[sequenceNo],[retries],[messagePriority],[userId],[bulkId],getdate())
OUTPUT deleted.*, $action, inserted.*;
GO

Gambar 7 menunjukkan baris yang dihapus, dan Gambar 8 menunjukkan baris yang diperbarui. Ini adalah kekuatan dari pernyataan MERGE. Kami dapat melakukan operasi penghapusan, penyisipan, dan pembaruan semua dalam satu pernyataan.

kesimpulan

Artikel ini meninjau penggunaan pernyataan MERGE untuk menyinkronkan data antara tabel online dan tabel riwayat sambil mempertahankan retensi yang diinginkan yang diperlukan di kedua tabel.

Ada banyak kasus penggunaan lain untuk pernyataan SQL Server MERGE yang tidak tercakup dalam artikel ini, tetapi mereka dieksplorasi dalam dokumentasi Microsoft. Sumber data yang ditentukan dalam klausa USING tidak terbatas pada tabel. Kumpulan hasil dari pernyataan SELECT eksplisit dapat menjadi data sumber. Ekspresi tabel umum juga bisa menjadi sumber data.

REFERENSI

MERGE di Transact-SQL


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jalankan prosedur tersimpan di prosedur tersimpan lain di server SQL

  2. Cara menggunakan PHP untuk terhubung ke sql server

  3. Cara Menonaktifkan Semua Batasan PERIKSA &Kunci Asing untuk Tabel di SQL Server (Contoh T-SQL)

  4. TODATETIMEOFFSET() Contoh di SQL Server

  5. SQL Server Internal:Operator Bermasalah Pt. Saya – Memindai