2013-10-22 27 views
6

Bu yüzden bugün garip bir SQL Server davranışı keşfettim.Benzersiz filtrelenmiş dizinle birleştirin

varsayalım böyle bir tablo id

╔════╦══════╦════════╗ 
║ id ║ name ║ active ║ 
╠════╬══════╬════════╣ 
║ 1 ║ a ║  0 ║ 
║ 2 ║ a ║  1 ║ 
╚════╩══════╩════════╝ 

birincil anahtar

olduğunu var Ve ben bir filtered unique index on name where active = 1 olduğunu varsayın. Şimdi sadece satırlarını satırları için aktif hale getirmek istiyorum, ilk satırı etkin değil ve ikinci satırı aktif olarak ayarlayın. Ben güncellemek yapmaya çalıştığınızda ince çalışır o

update Table1 set 
    active = n.active 
from Table1 as t 
inner join (values (1, 1), (2, 0)) as n(id, active) on n.id = t.id 

gibi. Ben birleştirme yapmaya çalışacağım Ama eğer:

merge Table1 as t 
using (values (1, 1), (2, 0)) as n(id, active) on n.id = t.id 
when matched then 
    update set active = n.active; 

eğer hata Cannot insert duplicate key row in object 'dbo.Table1' with unique index 'ix_Table1'. The duplicate key value is (a) ile başarısız oldu.

╔════╦══════╦════════╗ 
║ id ║ name ║ active ║ 
╠════╬══════╬════════╣ 
║ 1 ║ a ║  1 ║ 
║ 2 ║ a ║  0 ║ 
╚════╩══════╩════════╝ 

ve bu gibi birleştirme: Bu gibi tablo varsa

Hatta yabancı, (ilk satır = 1 ve ikinci sıra aktif etkin = 0 olması olan)

merge Table1 as t 
using (values (1, 0), (2, 1)) as n(id, active) on n.id = t.id 
when matched then 
    update set active = n.active; 

It , yeniden çalışır. Yani gerçekten birleştirme satır satır güncelleştirir ve her satırdan sonra indexe denetler gibi görünüyor. Benzersiz kısıtlamaları, filtre içermeyen benzersiz dizinleri kontrol ettim, her şey yolunda. Yalnızca birleştirme ve süzgeç dizini birleştirdiğimde başarısız olur.

Soru yani - bu bir hata olduğunu ve bunun ise en iyi çözüm bu ne için?

sql fiddle demo'da deneyebilirsiniz.

Ben sqlblog.com bu makale buldum

cevap

1

- MERGE Bug with Filtered Indexes, bu Paul White tarafından yazıldığı tarihli O geçici çözümler birkaç verdi

2012.: tüm sütunları ekleme

  • başvurulan Dizin anahtarının filtrelenmiş dizininin WHERE maddesi (INCLUDE yeterli değil); veya izleme bayrağı 8790 ile sorguyu yürütme örn. SEÇENEK (QUERYTRACEON 8790).

    merge Table1 as t 
    using (values (1, 1), (2, 0)) as n(id, active) on n.id = t.id 
    when matched then 
        update set active = n.active, id = n.id; 
    

    Ben de mümkün olduğunu düşünüyorum: biraz araştırma sonrasında

Ben güncelleştirme olarak birincil anahtar sütunu eklerseniz sorgu haline gelmesi, bu ok sonuçlar verdiğini saptadık updted dizininden sütun ekleyin, ancak henüz test etmediniz.

sql fiddle demo