Bir alt sorgu kullanarak SQL Silme


15

Aşağıdaki kod, geliştiricilerimizden biri tarafından yinelenen kayıtları tablodan silmek için eklendi:

DELETE  SubQuery

FROM
(
    SELECT  ID
            ,FK1
            ,FK2
            ,CreatedDateTime
            ,ROW_NUMBER() OVER(PARTITION BY FK1, FK2 ORDER BY CreatedDateTime) AS RowNumber

    FROM    Table
)
AS SubQuery

WHERE   RowNumber > 1

Kodu incelerken, işe yaramayacağını varsaydım, ancak test ortamımızda (SQL 2014) test edildiğini gösteriyor!

SQL, alt sorguyu çözmeyi ve kayıtları silmeyi nasıl biliyor table?

Yanıtlar:


14

subqueryKodunuzdaki sahip bir denir türetilmiş tablo . Temel tablo değil, sorgunun çalıştığı sırada "yaşayan" bir tablodur. Gibi görünümler (ayrıca denir inceledi tabloları ve son versiyonları içinde -) CTEs başka, 4 yoldur bir sorguya bir tablo içindeki "define" - onlar birçok yönden bir tabloya benzer. Şunları yapabilirsiniz selectonlardan, sen bunları kullanabilir fromveya joindiğer tablolara onlara (baz ya da değil!).

Bazı DBMS'lerde (tüm DBMS bunu aynı şekilde uygulamamıştır) bu tablolar / görünümler güncellenebilir . Ve "güncellenebilir" demek aynı zamandaupdate , insertiçine ya da deleteonlardan.

Yine de kısıtlamalar var ve bu bekleniyor. subquery2 (veya 17 tablo) bir birleşimi olduğunu düşünün . O zaman ne deleteanlama geliyor? (hangi tablolardan satırlar silinmelidir?) Güncellenebilir görünümler çok karmaşık bir konudur . İlişkisel teoride tanınmış bir uzman olan Chris Date tarafından yazılan, tamamen bu konuda yeni bir kitap (2012) var: Güncelleme ve İlişkisel Teoriyi Görüntüle .

Türetilmiş tablo (veya görünüm) çok basit bir sorgu olduğunda, yalnızca bir temel tabloya sahip olması (muhtemelen a ile kısıtlanmış olması WHERE) ve hayır GROUP BYolması durumunda, türetilmiş tablonun her satırı temel taban tablosundaki bir satıra karşılık gelir. kolay * güncellemek, eklemek veya silmek için.

Alt sorgunun içindeki kod daha karmaşık olduğunda, türetilmiş tablo / görünüm satırlarının temel taban tablolarından birindeki satırlara kadar izlenip izlenemeyeceğine bağlıdır.

SQL Server için, MSDN: Güncellenebilir Görünümler paragrafında daha fazla bilgi bulabilirsiniz CREATE VIEW.

Güncellenebilir Görünümler

Aşağıdaki koşullar geçerli olduğu sürece, temel alınan temel tablonun verilerini bir görünüm aracılığıyla değiştirebilirsiniz:

  • Herhangi içeren modifikasyonlar UPDATE, INSERTve DELETEsadece tek bir temel tablodan tablolar, şart referans sütunlar.

  • Görünümde değiştirilen sütunlar, tablo sütunlarındaki temel verilere doğrudan başvurmalıdır. Sütunlar, aşağıdakiler gibi başka bir şekilde türetilemez:

  • Bir toplama işlevi: AVG, COUNT, SUM, MIN, MAX, GROUPING, STDEV, STDEVP, VAR, ve VARP.

  • Bir hesaplama. Sütun, diğer sütunları kullanan bir ifadeden hesaplanamaz. Grubu operatörleri kullanılarak oluşturulur sütunlar UNION, UNION ALL, CROSSJOIN, EXCEPT, ve INTERSECT bir hesaplama miktarı ve aynı zamanda güncelleştirilebilir değildir.

  • Sütun etkilenmez değiştirilen GROUP BY, HAVINGveya DISTINCTmaddeleri.

  • TOPWITH CHECK OPTIONyan tümcesiyle birlikte görünümün select_statement öğesinde hiçbir yerde kullanılmaz .

Önceki kısıtlamalar FROM, tıpkı görünümün kendisi için geçerli olduğu gibi, görünümün yan tümcesindeki tüm alt sorgular için de geçerlidir. Genel olarak, Veritabanı Altyapısı, görünüm tanımından bir temel tablodaki değişiklikleri net bir şekilde izleyebilmelidir.


Aslında deletedaha kolay, daha az karmaşık update. SQL Server, temel tablonun hangi satırlarının silineceğini belirlemek için yalnızca birincil anahtarlara veya başka bir yola ihtiyaç duyar. Çünkü update, hesaplanmış bir sütunu güncelleyemeyeceğimiz ek (oldukça açık) bir kısıtlama vardır. Güncelleme yapmak için sorgunuzu değiştirmeyi deneyebilirsiniz. Güncellenmesi CreatedDateTimemuhtemelen işe yarayacaktır, ancak hesaplanan RowNumbersütunu güncellemeye çalışmak bir hataya neden olacaktır. Ve insertdaha da karmaşıktır, çünkü temel tablonun DEFAULTkısıtlaması olmayan tüm sütunları için değer sağlamak zorundayız .


4

Sorgu planına baktığınızda kolayca görebilirsiniz. Sizin durumunuzda, plan yalnızca satır numarasını işlemek için ek bir Segment ve Dizi Projesi operatörü içerir. Bu tür işlem yalnızca SQL Server temel tabloyu çözebildiğinde çalışır.

Alt sorgulardan ve CTE'lerden silme, özellikle yinelenenleri kaldırmak için tamamen desteklenir ve çok etkilidir. Ayrıca SQL Server'ın eski sürümlerinde kullanarak hatırlamak gibi görünüyor.

Daha çok eski bir blog yayınımda.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.