Aracılığıyla paylaş


BIRLEŞME (Transact-SQL)

Şunlar için geçerlidir:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics (dedicated SQL pool only)Microsoft Fabric'te SQL veritabanıMicrosoft Fabric'te Depo

deyimi MERGE , kaynak tabloyla birleştirmenin sonuçlarından hedef tabloda ekleme, güncelleştirme veya silme işlemlerini çalıştırır. Örneğin, bir tablodaki satırları diğer tabloda bulunan farklara göre ekleyerek, güncelleştirerek veya silerek iki tabloyu eşitleyin.

Bu makalede, seçilen ürün sürümüne göre farklı söz dizimi, bağımsız değişkenler, açıklamalar, izinler ve örnekler sağlanır. Sürüm açılan listesinden istediğiniz ürün sürümünü seçin.

Note

Doku Veri Ambarı'nda MERGE önizleme aşamasındadır.

Transact-SQL söz dizimi kuralları

Syntax

SQL Server ve Azure SQL Veritabanı söz dizimi:

[ WITH <common_table_expression> [,...n] ]
MERGE
    [ TOP ( expression ) [ PERCENT ] ]
    [ INTO ] <target_table> [ WITH ( <merge_hint> ) ] [ [ AS ] table_alias ]
    USING <table_source> [ [ AS ] table_alias ]
    ON <merge_search_condition>
    [ WHEN MATCHED [ AND <clause_search_condition> ]
        THEN <merge_matched> ] [ ...n ]
    [ WHEN NOT MATCHED [ BY TARGET ] [ AND <clause_search_condition> ]
        THEN <merge_not_matched> ]
    [ WHEN NOT MATCHED BY SOURCE [ AND <clause_search_condition> ]
        THEN <merge_matched> ] [ ...n ]
    [ <output_clause> ]
    [ OPTION ( <query_hint> [ ,...n ] ) ]
;

<target_table> ::=
{
    [ database_name . schema_name . | schema_name . ] [ [ AS ] target_table ]
    | @variable [ [ AS ] target_table ]
    | common_table_expression_name [ [ AS ] target_table ]
}

<merge_hint>::=
{
    { [ <table_hint_limited> [ ,...n ] ]
    [ [ , ] { INDEX ( index_val [ ,...n ] ) | INDEX = index_val }]
    }
}

<merge_search_condition> ::=
    <search_condition>

<merge_matched>::=
    { UPDATE SET <set_clause> | DELETE }

<merge_not_matched>::=
{
    INSERT [ ( column_list ) ]
        { VALUES ( values_list )
        | DEFAULT VALUES }
}

<clause_search_condition> ::=
    <search_condition>

Azure Synapse Analytics, Doku Veri Ambarı söz dizimi:

[ WITH <common_table_expression> [,...n] ]
MERGE
    [ INTO ] <target_table> [ [ AS ] table_alias ]
    USING <table_source> [ [ AS ] table_alias ]
    ON <merge_search_condition>
    [ WHEN MATCHED [ AND <clause_search_condition> ]
        THEN <merge_matched> ] [ ...n ]
    [ WHEN NOT MATCHED [ BY TARGET ] [ AND <clause_search_condition> ]
        THEN <merge_not_matched> ]
    [ WHEN NOT MATCHED BY SOURCE [ AND <clause_search_condition> ]
        THEN <merge_matched> ] [ ...n ]
    [ OPTION ( <query_hint> [ ,...n ] ) ]
;  -- The semi-colon is required, or the query will return a syntax error.

<target_table> ::=
{
    [ database_name . schema_name . | schema_name . ]
  target_table
}

<merge_search_condition> ::=
    <search_condition>

<merge_matched>::=
    { UPDATE SET <set_clause> | DELETE }

<merge_not_matched>::=
{
    INSERT [ ( column_list ) ]
        VALUES ( values_list )
}

<clause_search_condition> ::=
    <search_condition>

Arguments

ILE <common_table_expression>

deyimi kapsamında MERGE tanımlanan ve ortak tablo ifadesi olarak da bilinen geçici adlandırılmış sonuç kümesini veya görünümünü belirtir. Sonuç kümesi basit bir sorgudan türetilir ve deyimi tarafından başvurulur MERGE . Daha fazla bilgi için bkz. WITH common_table_expression (Transact-SQL).

TOP ( ifade ) [ YÜZDE ]

Etkilenen satırların sayısını veya yüzdesini belirtir. ifadesi bir sayı veya satırların yüzdesi olabilir. İfadede başvuruda bulunan TOP satırlar herhangi bir sırada düzenlenmemiştir. Daha fazla bilgi için bkz. TOP (Transact-SQL).

Yan TOP tümcesi, tüm kaynak tablo ve hedef tablo birleşiminin tamamı ile ekleme, güncelleştirme veya silme eylemi için uygun olmayan birleştirilmiş satırlar kaldırıldıktan sonra uygulanır. yan tümcesi TOP , birleştirilen satır sayısını belirtilen değere daha da azaltır. Bu eylemler (ekleme, güncelleştirme veya silme) kalan birleştirilmiş satırlara sıralanmamış bir şekilde uygulanır. Başka bir ifadeyle, satırların yan tümcelerde WHEN tanımlanan eylemler arasında dağıtıldığı bir sıra yoktur. Örneğin, (10) belirtilmesi TOP 10 satırı etkiler. Bu satırlardan 7'i güncelleştirilebilir ve 3'ünün eklenmesi veya 1'i silinebilir, 5'i güncelleştirilmiş, 4'ünün eklenmesi vb. olabilir.

Kaynak tablodaki filtreler olmadan deyimi, MERGE kaynak tabloda tablo taraması veya kümelenmiş dizin taramasının yanı sıra hedef tabloda tablo taraması veya kümelenmiş dizin taraması gerçekleştirebilir. Bu nedenle, birden çok toplu iş oluşturarak büyük bir tabloyu değiştirmek için yan tümcesi TOP kullanıldığında bile G/Ç performansı bazen etkilenir. Bu senaryoda, ardışık tüm toplu işlerde yeni satırların hedeflediğinden emin olmak önemlidir.

database_name

target_table bulunduğu veritabanının adı.

schema_name

target_table ait olduğu şemanın adı.

target_table

veri satırlarının <table_source> temel alınarak <clause_search_condition>eşleştirildiği tablo veya görünüm. target_table , deyiminin yan tümceleri tarafından WHEN belirtilen tüm ekleme, güncelleştirme veya silme işlemlerinin MERGE hedefidir.

target_table bir görünümse, bu görünüme yönelik tüm eylemler görünümleri güncelleştirme koşullarını karşılamalıdır. Daha fazla bilgi için bkz . Görünüm Aracılığıyla Verileri Değiştirme.

target_table uzak tablo olamaz. target_table hiçbir kural tanımlayamaz. target_table bellek için iyileştirilmiş bir tablo olamaz.

İpuçları olarak <merge_hint>belirtilebilir.

<merge_hint> Azure Synapse Analytics için desteklenmez.

[ AS ] table_alias

target_table tabloya başvurmak için alternatif bir ad.

table_source KULLANMA <>

temelinde<merge_search_condition>target_table'daki veri satırlarıyla eşleşen veri kaynağını belirtir. Bu eşleşmenin sonucu, deyiminin yan tümceleri WHEN tarafından MERGE gerçekleştirecek eylemleri belirler. <table_source> uzak tablo veya uzak tablolara erişen türetilmiş bir tablo olabilir.

<table_source> birden çok satır belirterek tablo oluşturmak için Transact-SQL tablo değeri oluşturucusunun kullanıldığı türetilmiş bir tablo olabilir.

<table_source> , birden çok satır belirterek tablo oluşturmak için kullanan SELECT ... UNION ALL türetilmiş bir tablo olabilir.

[ AS ] table_alias

table_source tabloya başvurmak için alternatif bir ad.

Bu yan tümcenin söz dizimi ve bağımsız değişkenleri hakkında daha fazla bilgi için bkz . FROM (Transact-SQL).

ON <merge_search_condition>

Nerede eşleşeceklerini belirlemek için <table_source> ile birleştirildiği koşulları belirtir.

Caution

Yalnızca hedef tablodan eşleşen amaçlar için kullanılacak sütunların belirtilmesi önemlidir. Diğer bir ifadeyle, hedef tablodan kaynak tablonun karşılık gelen sütunuyla karşılaştırılan sütunları belirtin. Yan tümcesindeki hedef tablodaki ON satırları filtreleyerek sorgu performansını geliştirmeye çalışma, örneğin belirtme AND NOT target_table.column_x = value. Bunu yapmak beklenmeyen ve yanlış sonuçlar döndürebilir.

EŞLENDİKİ ZAMAN <MERGE_MATCHED>

tarafından döndürülen <table_source> ON <merge_search_condition>satırlarla eşleşen ve ek arama koşullarını karşılayan *target_table tüm satırlarının yan tümcesine <merge_matched> göre güncelleştirildiğini veya silindiğini belirtir.

deyiminin MERGE en fazla iki WHEN MATCHED yan tümcesi olabilir. İki yan tümce belirtilirse, ilk yan tümceye bir AND<search_condition> yan tümce eşlik etmelidir. Herhangi bir satır için, ikinci WHEN MATCHED yan tümcesi yalnızca ilk yan tümce uygulanmazsa uygulanır. İki WHEN MATCHED yan tümce varsa, bir eylem ve UPDATE bir eylem belirtmelidir DELETE . UPDATE yan tümcesinde belirtildiğinde <merge_matched> ve <table_source>birden fazla <merge_search_condition> satır eşleşmesi olduğunda SQL Server bir hata döndürür. Deyimi MERGE aynı satırı birden çok kez güncelleştiremez veya aynı satırı güncelleştirip silemez.

EŞLEŞMEDIĞINDE [ HEDEFE GÖRE ] SONRA <merge_not_matched>

tarafından döndürülen her satır için <table_source> ON <merge_search_condition> bir satırla eşleşmeyen, ancak varsa ek bir arama koşuluna uyan bir satırın target_table eklendiğini belirtir. Eklenecek değerler yan tümcesi <merge_not_matched> tarafından belirtilir. Deyiminin MERGE tek bir WHEN NOT MATCHED [ BY TARGET ] yan tümcesi olabilir.

KAYNAKLA EŞLEŞMEDİYSE O ZAMAN <merge_matched>

tarafından döndürülen <table_source> ON <merge_search_condition>satırlarla eşleşmeyen ve herhangi bir ek arama koşulunu karşılayan *target_table tüm satırlarının yan tümcesine <merge_matched> göre güncelleştirildiğini veya silindiğini belirtir.

deyiminin MERGE en çok iki WHEN NOT MATCHED BY SOURCE yan tümcesi olabilir. İki yan tümce belirtilirse, ilk yan tümceye bir AND<clause_search_condition> yan tümce eşlik etmelidir. Herhangi bir satır için, ikinci WHEN NOT MATCHED BY SOURCE yan tümcesi yalnızca ilk yan tümce uygulanmazsa uygulanır. İki WHEN NOT MATCHED BY SOURCE yan tümce varsa, bir eylem ve UPDATE bir eylem belirtmelidir DELETE . içinde <clause_search_condition>yalnızca hedef tablodaki sütunlara başvurulabilir.

tarafından <table_source>hiçbir satır döndürülmezse, kaynak tablodaki sütunlara erişilemiyor. Yan tümcesinde <merge_matched> belirtilen güncelleştirme veya silme eylemi kaynak tablodaki sütunlara başvuruda bulunuyorsa, hata 207 (Geçersiz sütun adı) döndürülür. Örneğin, yan tümcesi WHEN NOT MATCHED BY SOURCE THEN UPDATE SET TargetTable.Col1 = SourceTable.Col1 kaynak tabloda erişilemez olduğundan Col1 deyiminin başarısız olmasına neden olabilir.

VE <clause_search_condition>

Geçerli bir arama koşulu belirtir. Daha fazla bilgi için bkz . Arama koşulu (Transact-SQL).

<table_hint_limited>

Deyimi tarafından yapılan ekleme, güncelleştirme veya silme eylemlerinin her biri için hedef tabloya uygulanacak bir veya daha fazla tablo ipucunu MERGE belirtir. WITH Anahtar sözcük ve parantezler gereklidir.

NOLOCK ve READUNCOMMITTED izin verilmez. Tablo ipuçları hakkında daha fazla bilgi için bkz. Tablo ipuçları (Transact-SQL).

Bir deyiminin TABLOCK hedefi olan bir tabloda ipucunun INSERT belirtilmesi, ipucunu belirtmeyle TABLOCKX aynı etkiye sahiptir. Masada özel bir kilit alınır. FORCESEEK belirtildiğinde, kaynak tabloyla birleştirilen hedef tablonun örtük örneğine uygulanır.

Caution

ile belirtilmesiREADPAST, kısıtlamaları ihlal WHEN NOT MATCHED [ BY TARGET ] THEN INSERT eden işlemlere neden INSERTUNIQUE olabilir.

İNDİS ( index_val [ ,... n ] )

Kaynak tabloyla örtük birleştirme yapmak için hedef tablodaki bir veya daha fazla dizinin adını veya kimliğini belirtir. Daha fazla bilgi için bkz. Tablo İpuçları (Transact-SQL).

<output_clause>

target_table herhangi bir sırada güncelleştirilmemiş, eklenmiş veya silinmiş her satır için bir satır döndürür. $action output yan tümcesinde belirtilebilir. $action , her satır için üç değerden birini döndüren nvarchar(10) türünde bir sütundur: INSERTbu UPDATEsatırda yapılan eyleme göre , veya DELETE. OUTPUT yan tümcesi, bir MERGEtarafından etkilenen satırları sorgulamak veya saymak için önerilen yoldur. Bu yan tümcenin bağımsız değişkenleri ve davranışı hakkında daha fazla bilgi için bkz . OUTPUT yan tümcesi (Transact-SQL).

OPTION ( <query_hint> [ ,... n ] )

Veritabanı Altyapısı'nın deyimini işleme biçimini özelleştirmek için iyileştirici ipuçlarının kullanıldığını belirtir. Daha fazla bilgi için bkz . Sorgu ipuçları (Transact-SQL).

<merge_matched>

tarafından döndürülen satırlarla eşleşmeyen ve ek arama koşullarını karşılayan <table_source> ON <merge_search_condition> satırlarına uygulanan güncelleştirme veya silme eylemini belirtir.

SET set_clause <GÜNCELLEŞTIRME>

Hedef tabloda güncelleştirilecek sütun veya değişken adlarının listesini ve bunların güncelleştirildiği değerleri belirtir.

Bu yan tümcenin bağımsız değişkenleri hakkında daha fazla bilgi için bkz . UPDATE (Transact-SQL). Bir değişkeni sütunla aynı değere ayarlamak desteklenmez.

DELETE

target_table içindeki satırlarla eşleşen satırların silindiğini belirtir.

<merge_not_matched>

Hedef tabloya eklenecek değerleri belirtir.

( column_list )

Verilerin eklendiği hedef tablonun bir veya daha fazla sütununun listesi. Sütunlar tek parçalı ad olarak belirtilmelidir, aksi halde MERGE deyimi başarısız olur. column_list ayraç içine alınmalı ve virgülle sınırlandırılmalıdır.

DEĞERLER ( values_list )

Hedef tabloya eklenecek değerleri döndüren sabitlerin, değişkenlerin veya ifadelerin virgülle ayrılmış listesi. İfadeler deyimi EXECUTE içeremez.

VARSAYıLAN DEĞERLER

Eklenen satırı her sütun için tanımlanan varsayılan değerleri içerecek şekilde zorlar.

Bu yan tümce hakkında daha fazla bilgi için bkz . INSERT (Transact-SQL).

<search_condition>

veya <merge_search_condition>belirteceğiniz <clause_search_condition> arama koşullarını belirtir. Bu yan tümcenin bağımsız değişkenleri hakkında daha fazla bilgi için bkz . Arama koşulu (Transact-SQL).

<graf arama düzeni>

Graf eşleştirme desenini belirtir. Bu yan tümcenin bağımsız değişkenleri hakkında daha fazla bilgi için bkz . KAÇINCI (Transact-SQL).

Remarks

deyimi için MERGE açıklanan koşullu davranış, iki tablo eşleşen özelliklerin karmaşık bir karışımına sahip olduğunda en iyi şekilde çalışır. Örneğin, yoksa satır ekleme veya eşleşiyorsa satırı güncelleştirme. Bir tabloyu başka bir tablonun satırlarına göre güncelleştirdiğinizde, , INSERTve deyimleriyle UPDATEperformansı ve DELETE ölçeklenebilirliği geliştirin. Örneğin:

INSERT tbl_A (col, col2)
SELECT col, col2
FROM tbl_B
WHERE NOT EXISTS (SELECT col FROM tbl_A A2 WHERE A2.col = tbl_B.col);

Üç MATCHED yan tümceden en az biri belirtilmelidir, ancak herhangi bir sırada belirtilebilir. Bir değişken aynı MATCHED yan tümcede birden çok kez güncelleştirilemez.

Deyimi tarafından MERGE hedef tabloda belirtilen herhangi bir ekleme, güncelleştirme veya silme eylemi, basamaklı bilgi tutarlılığı kısıtlamaları da dahil olmak üzere, üzerinde tanımlanan kısıtlamalarla sınırlıdır. IGNORE_DUP_KEY Hedef tablodaki benzersiz dizinler içinseON, MERGE bu ayarı yoksayar.

deyimi, MERGE deyim sonlandırıcısı olarak noktalı virgül (;) gerektirir. Sonlandırıcı olmadan bir MERGE deyim çalıştırıldığında hata 10713 oluştu.

sonrasında MERGEkullanıldığında , @@ROWCOUNT (Transact-SQL), istemciye eklenen, güncelleştirilen ve silinen toplam satır sayısını döndürür.

MERGE , veritabanı uyumluluk düzeyi veya daha yüksek olarak ayarlandığında 100 tam olarak ayrılmış bir anahtar sözcüktür. deyimi MERGE hem hem de 90100 veritabanı uyumluluk düzeyleri altında kullanılabilir; ancak veritabanı uyumluluk düzeyi olarak ayarlandığında 90anahtar sözcük tam olarak ayrılmaz.

Caution

MERGE kullanırken deyimini kullanmayın. MERGE ve kuyruğa alınmış güncelleştirme tetikleyicisi uyumlu değil. deyimini MERGE ve INSERTUPDATE deyimleriyle değiştirin.

Azure Synapse Analytics ile ilgili dikkat edilmesi gerekenler

Azure Synapse Analytics'te komut, MERGE SQL Server ve Azure SQL Veritabanı ile karşılaştırıldığında aşağıdaki farklılıklara sahiptir.

  • MERGE Dağıtım anahtarı sütununu güncelleştirmek için kullanılması, 10.0.17829.0'dan eski derlemelerde desteklenmez. Yükseltmeyi duraklatamıyor veya zorla yükseltemiyorsanız, 10.0.17829.0 sürümüne kadar geçici bir çözüm olarak ANSI UPDATE FROM ... JOIN deyimini kullanın.
  • Güncelleştirme MERGE , silme ve ekleme çifti olarak uygulanır. Bir güncelleştirmenin MERGE etkilenen satır sayısı silinen ve eklenen satırları içerir.
  • MERGE...WHEN NOT MATCHED INSERT sütunlu IDENTITY tablolar için desteklenmez.
  • Tablo değeri oluşturucu, kaynak tablonun yan tümcesinde USING kullanılamaz. Birden çok satır içeren türetilmiş bir kaynak tablo oluşturmak için kullanın SELECT ... UNION ALL .
  • Farklı dağıtım türlerine sahip tablolar için destek bu tabloda açıklanmıştır:
Azure Synapse Analytics'te MERGE CLAUSE Desteklenen TARGET dağıtım tablosu Desteklenen KAYNAK dağıtım tablosu Comment
WHEN MATCHED Tüm dağıtım türleri Tüm dağıtım türleri
NOT MATCHED BY TARGET HASH Tüm dağıtım türleri İki tabloyu eşitlemek için kullanın UPDATE/DELETE FROM...JOIN .
NOT MATCHED BY SOURCE Tüm dağıtım türleri Tüm dağıtım türleri

Tip

Dağıtım karma anahtarını içinde JOIN sütun olarak MERGE kullanıyorsanız ve yalnızca eşitlik karşılaştırması yapıyorsanız, yan tümcesindeki WHEN MATCHED THEN UPDATE SET sütun listesinden dağıtım anahtarını atlayabilirsiniz çünkü bu yedekli bir güncelleştirmedir.

Azure Synapse Analytics'te, MERGE 10.0.17829.0'dan eski derlemelerdeki komut, belirli koşullar altında hedef tabloyu tutarsız bir durumda bırakabilir ve satırlar yanlış dağıtıma yerleştirilerek daha sonra sorguların bazı durumlarda yanlış sonuçlar döndürmesine neden olabilir. Bu sorun 2 durumda oluşabilir:

Scenario Comment
Olay 1
İkincil dizinler veya kısıtlama içeren karma dağıtılmış MERGE bir TARGET tabloda kullanmaUNIQUE.
- Synapse SQL 10.0.15563.0 ve sonraki sürümlerinde düzeltildi.
- 10.0.15563.0'dan daha düşük bir sürüm döndürürse SELECT @@VERSION , bu düzeltmeyi almak için Synapse SQL havuzunu el ile duraklatın ve sürdürebilirsiniz.
- Düzeltme Synapse SQL havuzunuza uygulanana kadar, ikincil dizinleri veya MERGE kısıtlamaları olan dağıtılmış HASH tablolarda komutunu TARGET kullanmaktan UNIQUE kaçının.
Olay 2
KARMA dağıtılmış tablosunun dağıtım anahtarı sütununu güncelleştirmek için MERGE kullanma.
- Synapse SQL 10.0.17829.0 ve sonraki sürümlerde düzeltildi.
- 10.0.17829.0'dan daha düşük bir sürüm döndürürse SELECT @@VERSION , bu düzeltmeyi almak için Synapse SQL havuzunu el ile duraklatın ve sürdürebilirsiniz.
- Düzeltme Synapse SQL havuzunuza uygulanana kadar, dağıtım anahtarı sütunlarını güncelleştirmek için komutunu kullanmaktan MERGE kaçının.

Her iki senaryodaki güncelleştirmeler önceki yürütmeden MERGE etkilenen tabloları onarmaz. Etkilenen tabloları el ile tanımlamak ve onarmak için aşağıdaki betikleri kullanın.

Veritabanındaki hangi HASH dağıtılmış tabloların sorun oluşturabileceğini denetlemek için (daha önce bahsedilen durumlarda kullanılıyorsa) şu deyimi çalıştırın:

-- Case 1
SELECT a.name,
    c.distribution_policy_desc,
    b.type
FROM sys.tables a
INNER JOIN sys.indexes b
    ON a.object_id = b.object_id
INNER JOIN sys.pdw_table_distribution_properties c
    ON a.object_id = c.object_id
WHERE b.type = 2
    AND c.distribution_policy_desc = 'HASH';

-- Subject to Case 2, if distribution key value is updated in MERGE statement
SELECT a.name,
    c.distribution_policy_desc
FROM sys.tables a
INNER JOIN sys.pdw_table_distribution_properties c
    ON a.object_id = c.object_id
WHERE c.distribution_policy_desc = 'HASH';

için HASH dağıtılmış bir MERGE tablonun Olay 1 veya Servis Talebi 2'ye göre etkilenip etkilenmediğini denetlemek için, tablolarda satırların yanlış dağılıma sahip olup olmadığını incelemek için bu adımları izleyin. Döndürülürse no need for repair , bu tablo etkilenmez.

IF object_id('[check_table_1]', 'U') IS NOT NULL
    DROP TABLE [check_table_1]
GO

IF object_id('[check_table_2]', 'U') IS NOT NULL
    DROP TABLE [check_table_2]
GO

CREATE TABLE [check_table_1]
    WITH (DISTRIBUTION = ROUND_ROBIN) AS

SELECT <DISTRIBUTION_COLUMN> AS x
FROM <MERGE_TABLE>
GROUP BY <DISTRIBUTION_COLUMN>;
GO

CREATE TABLE [check_table_2]
    WITH (DISTRIBUTION = HASH (x)) AS

SELECT x
FROM [check_table_1];
GO

IF NOT EXISTS (
        SELECT TOP 1 *
        FROM (
            SELECT <DISTRIBUTION_COLUMN> AS x
            FROM <MERGE_TABLE>

            EXCEPT

            SELECT x
            FROM [check_table_2]
            ) AS tmp
        )
    SELECT 'no need for repair' AS result
ELSE
    SELECT 'needs repair' AS result
GO

IF object_id('[check_table_1]', 'U') IS NOT NULL
    DROP TABLE [check_table_1]
GO

IF object_id('[check_table_2]', 'U') IS NOT NULL
    DROP TABLE [check_table_2]
GO

Etkilenen tabloları onarmak için bu deyimleri çalıştırarak eski tablodaki tüm satırları yeni bir tabloya kopyalayın.

IF object_id('[repair_table_temp]', 'U') IS NOT NULL
    DROP TABLE [repair_table_temp];
GO

IF object_id('[repair_table]', 'U') IS NOT NULL
    DROP TABLE [repair_table];
GO

CREATE TABLE [repair_table_temp]
    WITH (DISTRIBUTION = ROUND_ROBIN) AS

SELECT *
FROM <MERGE_TABLE>;
GO

-- [repair_table] will hold the repaired table generated from <MERGE_TABLE>
CREATE TABLE [repair_table]
    WITH (DISTRIBUTION = HASH (<DISTRIBUTION_COLUMN>)) AS

SELECT *
FROM [repair_table_temp];
GO

IF object_id('[repair_table_temp]', 'U') IS NOT NULL
    DROP TABLE [repair_table_temp];
GO

Troubleshooting

Bazı senaryolarda, hedef MERGE veya kaynak tabloda 1.024 sütun olmasa bile deyimi hatasına CREATE TABLE failed because column <> in table <> exceeds the maximum of 1024 columns.neden olabilir. Bu senaryo, aşağıdaki koşullardan herhangi biri karşılandığında ortaya çıkabilir:

  • içinde bir , DELETEveya UPDATE SET işleminde INSERT birden çok sütun belirtilir (herhangi bir MERGEWHEN [NOT] MATCHED yan tümceye özel değildir)
  • Koşuldaki herhangi bir sütunun JOIN bir kümelenmemiş dizini (NCI) vardır
  • Hedef tablo dağıtıldı HASH

Bu hata bulunursa, önerilen geçici çözümler aşağıdaki gibidir:

  • Sütunlardan JOIN kümelenmemiş dizini (NCI) kaldırın veya NCI içermeyen sütunlarda birleştirin. Daha sonra temel tabloları sütunlara bir NCI JOIN içerecek şekilde güncelleştirirseniz, deyiminiz MERGE çalışma zamanında bu hataya karşı savunmasız olabilir. Daha fazla bilgi için bkz . DROP INDEX.
  • yerine UPDATE, DELETE ve MERGE deyimlerini kullanın.

Uygulamayı tetikleme

deyiminde belirtilen her ekleme, güncelleştirme veya silme eylemi için MERGE , SQL Server hedef tabloda tanımlanan ilgili AFTER tetikleyicileri tetikler, ancak ilk veya son tetikleyicilerin tetikleneceği eylemi garanti etmez. Aynı eylem için tanımlanan tetikleyiciler, belirttiğiniz sıraya göre belirlenir. Tetikleyici tetikleme sırasını ayarlama hakkında daha fazla bilgi için bkz. İlk ve Son Tetikleyicileri Belirtme.

Hedef tabloda bir INSTEAD deyimi tarafından MERGE gerçekleştirilen bir ekleme, güncelleştirme veya silme eylemi için tanımlanmış bir OF tetikleyicisi etkinleştirildiyse, deyiminde INSTEAD belirtilen tüm eylemler için of tetikleyicisinin etkinleştirilmesi MERGE gerekir.

INSTEAD herhangi bir UPDATE veya INSTEADDELETE OF tetikleyicisi tanımlanmışsa, güncelleştirme veya silme işlemleri çalıştırılamaz. Bunun yerine tetikleyiciler tetikler ve eklenen ve silinen tablolar buna göre doldurulur.

INSTEAD herhangi bir INSERT tetikleyici tanımlanmışsa ekleme işlemi gerçekleştirilmez. Bunun yerine, tablo buna göre doldurulur.

Note

Ayrı INSERT, UPDATEve DELETE deyimlerinden farklı olarak, tetikleyicinin içine yansıtılan @@ROWCOUNT satır sayısı daha yüksek olabilir. Herhangi bir @@ROWCOUNT tetikleyicinin AFTER içindeki (tetikleyicinin yakaladığı veri değişikliği deyimlerinden bağımsız olarak) tarafından MERGEetkilenen toplam satır sayısını yansıtır. Örneğin, bir MERGE deyim bir satır eklerse, bir satırı güncelleştirir ve bir satırı silerse, @@ROWCOUNT tetikleyici yalnızca deyimler için bildirilse bile herhangi bir AFTER tetikleyici için INSERT üç olur.

Permissions

SELECT Kaynak tablo ve INSERT, UPDATEveya DELETE hedef tablo üzerindeki izinler için izin gerektirir. Daha fazla bilgi için SELECT (Transact-SQL), INSERT (Transact-SQL), UPDATE (Transact-SQL) ve DELETE (Transact-SQL) makalelerindeki İzinler bölümüne bakın.

Dizin en iyi yöntemleri

deyimini MERGE kullanarak tek tek DML deyimlerini tek bir deyimle değiştirebilirsiniz. Bu, işlemler tek bir deyim içinde gerçekleştirildiğinden sorgu performansını geliştirebilir, bu nedenle kaynak ve hedef tablolardaki verilerin işlenme sayısını en aza indirir. Ancak performans artışları doğru dizinlerin, birleştirmelerin ve diğer önemli noktaların bulunmasına bağlıdır.

deyiminin MERGE performansını geliştirmek için aşağıdaki dizin yönergelerini öneririz:

  • kaynağı ile hedefi MERGEarasındaki birleştirmeyi kolaylaştırmak için dizinler oluşturun:
    • Kaynak tablodaki birleştirme sütunlarında, hedef tabloya birleştirme mantığını kapsayan anahtarları içeren bir dizin oluşturun. Mümkünse benzersiz olmalıdır.
    • Ayrıca, hedef tablodaki birleştirme sütunlarında bir dizin oluşturun. Mümkünse, benzersiz bir kümelenmiş dizin olmalıdır.
    • Bu iki dizin, tablolardaki verilerin sıralanmasını sağlar ve benzersizlik karşılaştırmanın performansına yardımcı olur. Sorgu iyileştiricinin yinelenen satırları bulup güncelleştirmek için ek doğrulama işlemi gerçekleştirmesi gerekmeyen ve ek sıralama işlemleri gerekmeyen sorgu performansı geliştirildi.
  • Deyimlerin hedefi olarak herhangi bir columnstore dizini biçimine sahip tablolardan MERGE kaçının. Tüm UPDAT'lerde olduğu gibi, hazırlanmış bir satır deposu tablosunu güncelleştirerek ve ardından veya DELETEyerine INSERT toplu UPDATE ve MERGEgerçekleştirerek columnstore dizinleriyle performansı daha iyi bulabilirsiniz.

MERGE için eşzamanlılık konusunda dikkat edilmesi gerekenler

Kilitleme açısından ayrık, MERGE ardışık INSERT, UPDATEve DELETE deyimlerinden farklıdır. MERGEyine de , INSERTve UPDATE işlemlerini yürütürDELETE, ancak farklı kilitleme mekanizmaları kullanır. Bazı uygulama gereksinimleri için ayrık INSERT, UPDATEve DELETE deyimleri yazmak daha verimli olabilir. Büyük ölçekte karmaşık MERGE eşzamanlılık sorunlarına neden olabilir veya gelişmiş sorun giderme gerektirebilir. Bu nedenle, üretime dağıtmadan önce herhangi bir MERGE deyimi kapsamlı bir şekilde test etme planı yapın.

MERGE deyimleri, aşağıdaki senaryolardaki (ancak bunlarla sınırlı olmamak üzere) ayrık INSERT, UPDATEve DELETE işlemleri için uygun bir değişikliktir:

  • Büyük satır sayılarını içeren ETL işlemleri, diğer eşzamanlı işlemlerin beklendiği* bir zamanda yürütülür. Yoğun eşzamanlılık beklendiğinde, ayrı INSERT, UPDATEve DELETE mantığı bir MERGE deyimden daha az engellemeyle daha iyi performans gösterebilir.
  • Küçük satır sayıları ve işlemleri içeren karmaşık işlemlerin uzun süre boyunca yürütülmesi pek olası değildir.
  • Dizinlerin en iyi yürütme planlarını sağlayacak şekilde tasarlandığı, dizin taramaları veya ideal olarak dizin aramaları için tablo taramalarından ve aramalardan kaçınıldığı kullanıcı tablolarını içeren karmaşık işlemler.

Eşzamanlılık konusunda dikkat edilmesi gereken diğer noktalar:

  • Benzersiz anahtarların tarafından hem eklenmesinin hem de güncelleştirilmesinin MERGEbeklendiği bazı senaryolarda, öğesinin belirtilmesi HOLDLOCK benzersiz anahtar ihlallerine karşı engeller. HOLDLOCK , diğer eşzamanlı işlemlerin SERIALIZABLE bu işlemin okuduğu verileri değiştirmesine izin vermeyen işlem yalıtım düzeyinin eş anlamlısıdır. SERIALIZABLE en güvenli yalıtım düzeyidir, ancak okuma işlemleri devam ederken hayalet satırların eklenmesini veya güncelleştirilmesini önlemek için veri aralıklarındaki kilitleri koruyan diğer işlemlerle en az eşzamanlılık sağlar. hakkında HOLDLOCKdaha fazla bilgi için bkz. Tablo İpuçları ve SET TRANSACTION ISOLATION LEVEL (Transact-SQL).

JOIN en iyi yöntemleri

deyiminin performansını MERGE geliştirmek ve doğru sonuçların elde edilmesini sağlamak için aşağıdaki birleştirme yönergelerini öneririz:

  • Yalnızca kaynak ve hedef tablolardaki ON <merge_search_condition> veri eşleştirme ölçütlerini belirleyen yan tümcesinde arama koşullarını belirtin. Diğer bir ifadeyle, yalnızca hedef tablodaki kaynak tablonun karşılık gelen sütunlarıyla karşılaştırılan sütunları belirtin.
  • Sabit gibi diğer değerlerle karşılaştırmalar eklemeyin.

Kaynak veya hedef tablolardaki satırları filtrelemek için aşağıdaki yöntemlerden birini kullanın.

  • Uygun WHEN yan tümcede satır filtreleme için arama koşulunu belirtin. Örneğin, WHEN NOT MATCHED AND S.EmployeeName LIKE 'S%' THEN INSERT....
  • Kaynak veya hedefte filtrelenmiş satırları döndüren bir görünüm tanımlayın ve görünüme kaynak veya hedef tablo olarak başvurun. Görünüm hedef tabloda tanımlanmışsa, görünüme yönelik tüm eylemler görünümleri güncelleştirme koşullarını karşılamalıdır. Görünüm kullanarak verileri güncelleştirme hakkında daha fazla bilgi için bkz. Görünüm Aracılığıyla Verileri Değiştirme.
  • WITH <common table expression> Kaynak veya hedef tablolardaki satırları filtrelemek için yan tümcesini kullanın. Bu yöntem yan tümcesinde ek arama ölçütleri belirtmeye ON benzer ve yanlış sonuçlar verebilir. Bu yöntemi kullanmaktan kaçınmanızı veya uygulamadan önce kapsamlı bir şekilde test yapmanızı öneririz.

deyimindeki MERGE birleştirme işlemi, deyimindeki birleştirme SELECT işlemiyle aynı şekilde iyileştirilmiştir. Başka bir ifadeyle, SQL Server birleştirmeyi işlerken sorgu iyileştiricisi birleştirmeyi işlemek için en verimli yöntemi (çeşitli olasılıklar dışında) seçer. Kaynak ve hedef benzer boyutta olduğunda ve daha önce açıklanan dizin yönergeleri kaynak ve hedef tablolara uygulandığında, birleştirme birleştirme işleci en verimli sorgu planıdır. Bunun nedeni, her iki tablonun da bir kez taranmış olması ve verileri sıralamaya gerek olmamasıdır. Kaynak hedef tablodan küçük olduğunda iç içe döngü işleci tercih edilir.

deyiminde yan tümcesini belirterek belirli bir birleştirmenin OPTION (<query_hint>)MERGE kullanılmasını zorlayabilirsiniz. Bu birleştirme türü dizinleri kullanmadığından, deyimler için MERGE sorgu ipucu olarak karma birleştirmeyi kullanmamanızı öneririz.

Parametreleştirme en iyi yöntemleri

SELECTBir , INSERT, veya UPDATEDELETE deyimi parametresiz yürütülürse, SQL Server sorgu iyileştiricisi deyimi dahili olarak parametreleştirmeyi seçebilir. Bu, sorguda yer alan tüm değişmez değerlerin parametrelerle değiştirildiğini gösterir. Örneğin, deyimi INSERT dbo.MyTable (Col1, Col2) VALUES (1, 10)dahili olarak olarak INSERT dbo.MyTable (Col1, Col2) VALUES (@p1, @p2)uygulanabilir. Basit parametreleştirme olarak adlandırılan bu işlem, ilişkisel altyapının yeni SQL deyimlerini mevcut, önceden derlenmiş yürütme planlarıyla eşleştirme becerisini artırır. Sorgu derlemelerinin ve yeniden derlemelerinin sıklığı azaldığından sorgu performansı iyileştirilebilir. Sorgu iyileştiricisi deyimlere basit parametreleştirme işlemini MERGE uygulamaz. Bu nedenle, MERGE değişmez değerler içeren deyimler, deyimi her INSERT yürütürken yeni bir plan derlendiğinden tek tek UPDATE, DELETEveya MERGE deyimleri gerçekleştiremeyebilir.

Sorgu performansını geliştirmek için aşağıdaki parametreleştirme yönergelerini öneririz:

  • yan tümcesindeki ON <merge_search_condition> ve deyiminin WHEN yan tümcelerindeki tüm değişmez değerleri parametreleştirin MERGE . Örneğin, değişmez değerleri uygun giriş parametreleriyle değiştirerek deyimini saklı yordama dahil MERGE edebilirsiniz.
  • Deyimi parametreleştiremiyorsanız, türünde TEMPLATE bir plan kılavuzu oluşturun ve plan kılavuzunda sorgu ipucunu belirtin PARAMETERIZATION FORCED . Daha fazla bilgi için bkz. Plan Kılavuzlarını Kullanarak Sorgu Parametreleştirme Davranışını Belirtme.
  • Deyimler veritabanında sık sık yürütülürse MERGE , veritabanındaki PARAMETERIZATION seçeneğini olarak FORCEDayarlamayı göz önünde bulundurun. Bu seçeneği ayarlarken dikkatli olun. Bu PARAMETERIZATION seçenek, veritabanı düzeyinde bir ayardır ve veritabanındaki tüm sorguların nasıl işlendiğini etkiler. Daha fazla bilgi için bkz . Zorlamalı Parametreleştirme.
  • Plan kılavuzlarına daha yeni ve daha kolay bir alternatif olarak, Sorgu Deposu ipuçlarıyla benzer bir stratejiyi göz önünde bulundurun. Daha fazla bilgi için bkz. Sorgu Deposu ipuçları.

TOP yan tümcesi en iyi yöntemleri

deyiminde MERGETOP yan tümcesi, kaynak tablo ve hedef tablo birleştirildikten sonra etkilenen satırların sayısını veya yüzdesini belirtir ve ekleme, güncelleştirme veya silme eylemi için uygun olmayan satırlar kaldırıldıktan sonra. Yan tümcesi TOP , birleştirilen satırların sayısını belirtilen değere daha da azaltır ve kalan birleştirilen satırlara sıralamasız bir şekilde ekleme, güncelleştirme veya silme eylemleri uygulanır. Başka bir ifadeyle, satırların yan tümcelerde WHEN tanımlanan eylemler arasında dağıtıldığı bir sıra yoktur. Örneğin, belirtilmesi TOP (10) 10 satırı etkiler; bu satırlardan 7'i güncelleştirilebilir ve 3'ünün eklenmesi veya 1'i silinebilir, 5'i güncelleştirilebilir, 4'ünün eklenmesi vb. olabilir.

Toplu olarak büyük bir tabloda veri işleme dili (DML) işlemleri gerçekleştirmek için yan tümcesinin TOP kullanılması yaygın bir durumdur. Deyimindeki yan tümcesini TOPMERGE bu amaçla kullanırken aşağıdaki etkileri anlamak önemlidir.

  • G/Ç performansı etkilenebilir.

    deyimi MERGE hem kaynak hem de hedef tabloların tam tablo taramasını gerçekleştirir. İşlemin toplu işlemlere bölünmesi, toplu iş başına gerçekleştirilen yazma işlemlerinin sayısını azaltır; ancak, her toplu işlem kaynak ve hedef tabloların tam tablo taramasını gerçekleştirir. Sonuçta elde edilen okuma etkinliği, sorgunun performansını ve tablolardaki diğer eşzamanlı etkinlikleri etkileyebilir.

  • Yanlış sonuçlar oluşabilir.

    Ardışık tüm toplu işlerde yeni satırların hedeflendiğinden veya hedef tabloya yanlış yinelenen satırların eklenmesi gibi istenmeyen davranışlar oluştuğundan emin olmak önemlidir. Bu durum, kaynak tablo hedef toplu işte olmayan ancak genel hedef tabloda yer alan bir satır içerdiğinde oluşabilir. Doğru sonuçlar elde etmek için:

    • ON Mevcut hedef satırları etkileyen ve gerçekten yeni olan kaynak satırları belirlemek için yan tümcesini kullanın.
    • Hedef satırın WHEN MATCHED önceki bir toplu işlem tarafından zaten güncelleştirilip güncelleştirilmediğini belirlemek için yan tümcesinde ek bir koşul kullanın.
    • Yan tümcesinde WHEN MATCHED ve SET mantıkta ek bir koşul kullanarak aynı satırın iki kez güncelleştirileebileceğini doğrulayın.

TOP Yan tümcesi yalnızca bu yan tümceler uygulandıktan sonra uygulandığından, her yürütme gerçekten eşleşmeyen bir satır ekler veya mevcut bir satırı güncelleştirir.

Toplu yükleme en iyi yöntemleri

deyimi, MERGE yan tümcesini tablo kaynağı olarak belirterek bir kaynak veri dosyasındaki verileri verimli bir şekilde hedef tabloya OPENROWSET(BULK...) yüklemek için kullanılabilir. Bunu yaptığınızda, dosyanın tamamı tek bir toplu işlemle işlenir.

Toplu birleştirme işleminin performansını geliştirmek için aşağıdaki yönergeleri öneririz:

  • Hedef tablodaki birleştirme sütunlarında kümelenmiş bir dizin oluşturun.

  • Toplu yükleme MERGEsırasında hedef tabloda diğer benzersiz olmayan, kümelenmemiş dizinleri devre dışı bırakın, daha sonra etkinleştirin. Bu, gecelik toplu veri işlemleri için yaygın ve kullanışlıdır.

  • Kaynak veri dosyasının ORDERUNIQUE nasıl sıralanacağını belirtmek için yan tümcesindeki ve OPENROWSET(BULK...) ipuçlarını kullanın.

    Varsayılan olarak, toplu işlem veri dosyasının sıralı olmadığını varsayar. Bu nedenle, kaynak verilerin hedef tablodaki kümelenmiş dizine göre sıralanması ve ipucunun ORDER sorgu iyileştiricisinin daha verimli bir sorgu planı oluşturabilmesi için sırayı belirtmek için kullanılması önemlidir. İpuçları çalışma zamanında doğrulanır; veri akışı belirtilen ipuçlarına uymuyorsa bir hata oluşur.

Bu yönergeler birleştirme anahtarlarının benzersiz olmasını ve kaynak dosyadaki verilerin sıralama düzeninin hedef tabloyla eşleşmesini sağlar. Ek sıralama işlemleri gerekli olmadığından ve gereksiz veri kopyaları gerekmediğinden sorgu performansı iyileştirildi.

MERGE performansını ölçme ve tanılama

Aşağıdaki özellikler, deyimlerin performansını MERGE ölçmenize ve tanılamanıza yardımcı olabilir.

Examples

A. Tek bir deyimdeki bir tabloda INSERT ve UPDATE işlemleri yapmak için MERGE kullanma

Bir tablodaki bir veya daha fazla sütunu eşleşen bir satır varsa güncelleştirmek yaygın bir senaryodur. Alternatif olarak, eşleşen bir satır yoksa verileri yeni satır olarak da ekleyebilirsiniz. Genellikle her iki senaryoyu da parametreleri uygun UPDATE ve INSERT deyimlerini içeren bir saklı yordama geçirerek yaparsınız. deyimiyle MERGE , her iki görevi de tek bir deyimde gerçekleştirebilirsiniz. Aşağıdaki örnek, AdventureWorks2025 veritabanında hem bir INSERT ifade hem UPDATE de bir ifade içeren bir işlem içermektedir. Daha sonra yordam, tek MERGE bir deyim kullanılarak eşdeğer işlemleri çalıştıracak şekilde değiştirilir.

CREATE PROCEDURE dbo.InsertUnitMeasure @UnitMeasureCode NCHAR(3), @Name NVARCHAR(25)
AS
BEGIN
    SET NOCOUNT ON;

    -- Update the row if it exists.
    UPDATE Production.UnitMeasure
    SET Name = @Name
    WHERE UnitMeasureCode = @UnitMeasureCode

    -- Insert the row if the UPDATE statement failed.
    IF (@@ROWCOUNT = 0)
    BEGIN
        INSERT INTO Production.UnitMeasure (
            UnitMeasureCode,
            Name
        )
        VALUES (@UnitMeasureCode, @Name)
    END
END;
GO

-- Test the procedure and return the results.
EXEC InsertUnitMeasure @UnitMeasureCode = 'ABC', @Name = 'Test Value';

SELECT UnitMeasureCode, Name
FROM Production.UnitMeasure
WHERE UnitMeasureCode = 'ABC';
GO

-- Rewrite the procedure to perform the same operations using the
-- MERGE statement.
-- Create a temporary table to hold the updated or inserted values
-- from the OUTPUT clause.
CREATE TABLE #MyTempTable (
    ExistingCode NCHAR(3),
    ExistingName NVARCHAR(50),
    ExistingDate DATETIME,
    ActionTaken NVARCHAR(10),
    NewCode NCHAR(3),
    NewName NVARCHAR(50),
    NewDate DATETIME
);
GO

ALTER PROCEDURE dbo.InsertUnitMeasure @UnitMeasureCode NCHAR(3),
    @Name NVARCHAR(25)
AS
BEGIN
    SET NOCOUNT ON;

    MERGE Production.UnitMeasure AS tgt
    USING (SELECT @UnitMeasureCode, @Name) AS src(UnitMeasureCode, Name)
        ON (tgt.UnitMeasureCode = src.UnitMeasureCode)
    WHEN MATCHED
        THEN
            UPDATE
            SET Name = src.Name
    WHEN NOT MATCHED
        THEN
            INSERT (UnitMeasureCode, Name)
            VALUES (src.UnitMeasureCode, src.Name)
    OUTPUT deleted.*,
        $action,
        inserted.*
    INTO #MyTempTable;
END;
GO

-- Test the procedure and return the results.
EXEC InsertUnitMeasure @UnitMeasureCode = 'ABC', @Name = 'New Test Value';
EXEC InsertUnitMeasure @UnitMeasureCode = 'XYZ', @Name = 'Test Value';
EXEC InsertUnitMeasure @UnitMeasureCode = 'ABC', @Name = 'Another Test Value';

SELECT * FROM #MyTempTable;

-- Cleanup
DELETE FROM Production.UnitMeasure
WHERE UnitMeasureCode IN ('ABC', 'XYZ');

DROP TABLE #MyTempTable;
GO
CREATE PROCEDURE dbo.InsertUnitMeasure @UnitMeasureCode NCHAR(3),
    @Name NVARCHAR(25)
AS
BEGIN
    SET NOCOUNT ON;

    -- Update the row if it exists.
    UPDATE Production.UnitMeasure
    SET Name = @Name
    WHERE UnitMeasureCode = @UnitMeasureCode

    -- Insert the row if the UPDATE statement failed.
    IF (@@ROWCOUNT = 0)
    BEGIN
        INSERT INTO Production.UnitMeasure (
            UnitMeasureCode,
            Name
        )
        VALUES (@UnitMeasureCode, @Name)
    END
END;
GO

-- Test the procedure and return the results.
EXEC InsertUnitMeasure @UnitMeasureCode = 'ABC', @Name = 'Test Value';

SELECT UnitMeasureCode, Name
FROM Production.UnitMeasure
WHERE UnitMeasureCode = 'ABC';
GO

-- Rewrite the procedure to perform the same operations using the
-- MERGE statement.
ALTER PROCEDURE dbo.InsertUnitMeasure @UnitMeasureCode NCHAR(3),
    @Name NVARCHAR(25)
AS
BEGIN
    SET NOCOUNT ON;

    MERGE Production.UnitMeasure AS tgt
    USING (
        SELECT @UnitMeasureCode,
            @Name
        ) AS src(UnitMeasureCode, Name)
        ON (tgt.UnitMeasureCode = src.UnitMeasureCode)
    WHEN MATCHED
        THEN
            UPDATE SET Name = src.Name
    WHEN NOT MATCHED
        THEN
            INSERT (UnitMeasureCode, Name)
            VALUES (src.UnitMeasureCode, src.Name);
END;
GO

-- Test the procedure and return the results.
EXEC InsertUnitMeasure @UnitMeasureCode = 'ABC', @Name = 'New Test Value';
EXEC InsertUnitMeasure @UnitMeasureCode = 'XYZ', @Name = 'Test Value';
EXEC InsertUnitMeasure @UnitMeasureCode = 'ABC', @Name = 'Another Test Value';

-- Cleanup
DELETE FROM Production.UnitMeasure
WHERE UnitMeasureCode IN ('ABC', 'XYZ');
GO

B. Tek bir deyimdeki tabloda UPDATE ve DELETE işlemleri yapmak için MERGE kullanma

Aşağıdaki örnek, tabloda işlenen SalesOrderDetail emirlere göre AdventureWorks2025 örnek veritabanındaki tabloyu günlük olarak güncellemek ProductInventory için kullanırMERGE. Quantity Tablodaki ProductInventory her ürün SalesOrderDetail için her gün verilen sipariş sayısı çıkarılarak tablonun sütunu güncelleştirilir. Bir ürünün sipariş sayısı bir ürünün stok düzeyini 0 veya daha düşük bir değere düşürürse, söz konusu ürünün satırı tablodan ProductInventory silinir.

CREATE PROCEDURE Production.usp_UpdateInventory @OrderDate DATETIME
AS
MERGE Production.ProductInventory AS tgt
USING (
    SELECT ProductID,
        SUM(OrderQty)
    FROM Sales.SalesOrderDetail AS sod
    INNER JOIN Sales.SalesOrderHeader AS soh
        ON sod.SalesOrderID = soh.SalesOrderID
            AND soh.OrderDate = @OrderDate
    GROUP BY ProductID
    ) AS src(ProductID, OrderQty)
    ON (tgt.ProductID = src.ProductID)
WHEN MATCHED
    AND tgt.Quantity - src.OrderQty <= 0
    THEN
        DELETE
WHEN MATCHED
    THEN
        UPDATE
        SET tgt.Quantity = tgt.Quantity - src.OrderQty,
            tgt.ModifiedDate = GETDATE()
OUTPUT $action,
    Inserted.ProductID,
    Inserted.Quantity,
    Inserted.ModifiedDate,
    Deleted.ProductID,
    Deleted.Quantity,
    Deleted.ModifiedDate;
GO

EXECUTE Production.usp_UpdateInventory '20030501';
CREATE PROCEDURE Production.usp_UpdateInventory @OrderDate DATETIME
AS
MERGE Production.ProductInventory AS tgt
USING (
    SELECT ProductID,
        SUM(OrderQty)
    FROM Sales.SalesOrderDetail AS sod
    INNER JOIN Sales.SalesOrderHeader AS soh
        ON sod.SalesOrderID = soh.SalesOrderID
            AND soh.OrderDate = @OrderDate
    GROUP BY ProductID
    ) AS src(ProductID, OrderQty)
    ON (tgt.ProductID = src.ProductID)
WHEN MATCHED
    AND tgt.Quantity - src.OrderQty <= 0
    THEN
        DELETE
WHEN MATCHED
    THEN
        UPDATE
        SET tgt.Quantity = tgt.Quantity - src.OrderQty,
            tgt.ModifiedDate = GETDATE();
GO

EXECUTE Production.usp_UpdateInventory '20030501';

C. Türetilmiş bir kaynak tablo kullanarak hedef tabloda UPDATE ve INSERT işlemleri yapmak için MERGE kullanma

Aşağıdaki örnek, AdventureWorks2025 veritabanındaki tabloyu SalesReason satır güncelleme veya ekleme yoluyla değiştirmek için kullanılırMERGE.

Kaynak tablodaki değeri NewName hedef tablonunName ( sütunundaki bir değerle eşleştiğindeSalesReason), ReasonType sütun hedef tabloda güncelleştirilir. değeri NewName eşleşmediğinde, kaynak satır hedef tabloya eklenir. Kaynak tablo, kaynak tablo için birden çok satır belirtmek üzere Transact-SQL tablo değeri oluşturucuyu kullanan türetilmiş bir tablodur. Türetilmiş bir tabloda tablo değeri oluşturucuyu kullanma hakkında daha fazla bilgi için bkz. Tablo Değeri Oluşturucu (Transact-SQL).

Yan OUTPUT tümcesi deyimlerin MERGE sonucunu sorgulamak için yararlı olabilir. Daha fazla bilgi için bkz . OUTPUT yan tümcesi (Transact-SQL). Örnek ayrıca yan tümcesinin OUTPUT sonuçlarının bir tablo değişkeninde nasıl depo yapılacağını da gösterir. Ardından eklenen ve güncelleştirilen satırların MERGE sayısını döndüren basit bir seçme işlemi çalıştırarak deyiminin sonuçlarını özetlersiniz.

-- Create a temporary table variable to hold the output actions.
DECLARE @SummaryOfChanges TABLE (Change VARCHAR(20));

MERGE INTO Sales.SalesReason AS tgt
USING (
    VALUES ('Recommendation', 'Other'),
        ('Review', 'Marketing'),
        ('Internet', 'Promotion')
    ) AS src(NewName, NewReasonType)
    ON tgt.Name = src.NewName
WHEN MATCHED
    THEN
        UPDATE
        SET ReasonType = src.NewReasonType
WHEN NOT MATCHED BY TARGET
    THEN
        INSERT (Name, ReasonType)
        VALUES (NewName, NewReasonType)
OUTPUT $action
INTO @SummaryOfChanges;

-- Query the results of the table variable.
SELECT Change,
    COUNT(*) AS CountPerChange
FROM @SummaryOfChanges
GROUP BY Change;

Kaynak tablodaki değeri NewName hedef tablonunName ( sütunundaki bir değerle eşleştiğindeSalesReason), ReasonType sütun hedef tabloda güncelleştirilir. değeri NewName eşleşmediğinde, kaynak satır hedef tabloya eklenir. Kaynak tablo, kaynak tablo için birden çok satır belirtmek için kullanan SELECT ... UNION ALL türetilmiş bir tablodur.

MERGE INTO Sales.SalesReason AS tgt
USING (
    SELECT 'Recommendation', 'Other'
    UNION ALL
    SELECT 'Review', 'Marketing'
    UNION ALL
    SELECT 'Internet', 'Promotion'
    ) AS src(NewName, NewReasonType)
    ON tgt.Name = src.NewName
WHEN MATCHED
    THEN
        UPDATE SET ReasonType = src.NewReasonType
WHEN NOT MATCHED BY TARGET
    THEN
        INSERT (Name, ReasonType)
        VALUES (NewName, NewReasonType);

D. MERGE deyiminin sonuçlarını başka bir tabloya ekleme

Aşağıdaki örnek, bir deyiminin OUTPUT yan tümcesinden döndürülen verileri yakalar ve bu verileri başka bir MERGE tabloya ekler. Bu MERGE ifade, tabloda işlenen SalesOrderDetail emirlere göre AdventureWorks2025 veritabanındaki tablonun ProductInventory sütununu güncellerQuantity. Örnek, güncelleştirilmiş satırları yakalar ve stok değişikliklerini izlemek için kullanılan başka bir tabloya ekler.

CREATE TABLE Production.UpdatedInventory (
    ProductID INT NOT NULL,
    LocationID INT,
    NewQty INT,
    PreviousQty INT,
    CONSTRAINT PK_Inventory PRIMARY KEY CLUSTERED (
        ProductID,
        LocationID
        )
    );
GO

INSERT INTO Production.UpdatedInventory
SELECT ProductID, LocationID, NewQty, PreviousQty
FROM (
    MERGE Production.ProductInventory AS pi
    USING (
        SELECT ProductID, SUM(OrderQty)
        FROM Sales.SalesOrderDetail AS sod
        INNER JOIN Sales.SalesOrderHeader AS soh
            ON sod.SalesOrderID = soh.SalesOrderID
                AND soh.OrderDate BETWEEN '20030701'
                    AND '20030731'
        GROUP BY ProductID
        ) AS src(ProductID, OrderQty)
        ON pi.ProductID = src.ProductID
    WHEN MATCHED
        AND pi.Quantity - src.OrderQty >= 0
        THEN
            UPDATE SET pi.Quantity = pi.Quantity - src.OrderQty
    WHEN MATCHED
        AND pi.Quantity - src.OrderQty <= 0
        THEN
            DELETE
    OUTPUT $action,
        Inserted.ProductID,
        Inserted.LocationID,
        Inserted.Quantity AS NewQty,
        Deleted.Quantity AS PreviousQty
    ) AS Changes(Action, ProductID, LocationID, NewQty, PreviousQty)
WHERE Action = 'UPDATE';
GO

E. Graph veritabanındaki bir hedef kenar tablosunda INSERT veya UPDATE yapmak için MERGE kullanma

Bu örnekte düğüm tabloları Person ve City bir kenar tablosu livesInoluşturursunuz. Kenarda MERGE deyimini livesIn kullanır ve kenar ile arasında zaten yoksa yeni bir PersonCitysatır eklersiniz. Kenar zaten varsa, kenarda livesIn StreetAddress özniteliğini güncelleştirmeniz gerekir.

-- CREATE node and edge tables
CREATE TABLE Person
(
    ID INTEGER PRIMARY KEY,
    PersonName VARCHAR(100)
)
AS NODE
GO

CREATE TABLE City
(
    ID INTEGER PRIMARY KEY,
    CityName VARCHAR(100),
    StateName VARCHAR(100)
)
AS NODE
GO

CREATE TABLE livesIn
(
    StreetAddress VARCHAR(100)
)
AS EDGE
GO

-- INSERT some test data into node and edge tables
INSERT INTO Person VALUES (1, 'Ron'), (2, 'David'), (3, 'Nancy')
GO

INSERT INTO City VALUES (1, 'Redmond', 'Washington'), (2, 'Seattle', 'Washington')
GO

INSERT livesIn SELECT P.$node_id, C.$node_id, c
FROM Person P, City C, (values (1,1, '123 Avenue'), (2,2,'Main Street')) v(a,b,c)
WHERE P.id = a AND C.id = b
GO

-- Use MERGE to update/insert edge data
CREATE OR ALTER PROCEDURE mergeEdge
    @PersonId integer,
    @CityId integer,
    @StreetAddress varchar(100)
AS
BEGIN
    MERGE livesIn
        USING ((SELECT @PersonId, @CityId, @StreetAddress) AS T (PersonId, CityId, StreetAddress)
                JOIN Person ON T.PersonId = Person.ID
                JOIN City ON T.CityId = City.ID)
        ON MATCH (Person-(livesIn)->City)
    WHEN MATCHED THEN
        UPDATE SET StreetAddress = @StreetAddress
    WHEN NOT MATCHED THEN
        INSERT ($from_id, $to_id, StreetAddress)
        VALUES (Person.$node_id, City.$node_id, @StreetAddress) ;
END
GO

-- Following will insert a new edge in the livesIn edge table
EXEC mergeEdge 3, 2, '4444th Avenue'
GO

-- Following will update the StreetAddress on the edge that connects Ron to Redmond
EXEC mergeEdge 1, 1, '321 Avenue'
GO

-- Verify that all the address were added/updated correctly
SELECT PersonName, CityName, StreetAddress
FROM Person , City , livesIn
WHERE MATCH(Person-(livesIn)->city)
GO