Dinamik filtreleme, grup oluşturma ve birden fazla parametreye göre agregasyon ile analitik raporlar, BI ve DataWareHouse uygulamalarının temelini oluşturur. Daha önce bu tür görevler yalnızca statik sorgular aracılığıyla çözülebiliyordu, ancak taleplerin artmasıyla birlikte SQL'in dinamik olarak anlık oluşturulması ihtiyacı ortaya çıktı: grup alanları ve sayısı kullanıcı veya uygulama tarafından belirleniyor.
Sorun — grup ve agregasyon için tüm alan varyasyonlarını önceden belirlemenin imkansızlığı. Sorguları dinamik olarak oluşturmak gerekir, bu da hatalar ve plansız sorgular ve uygun olmayan dizinler kullanımı ile performans düşüklüğüne yol açabilir.
Çözüm — dinamik SQL kullanarak sorgu oluşturulması (örneğin, T-SQL'de EXEC veya sp_executesql aracılığıyla), kullanıcı parametrelerinden SELECT, GROUP BY ve ilgili agregat fonksiyonlar için alanların listesinin oluşturulması. Bu arada, alan isimlerinin dikkatlice kaçış karakteri ile işlenmesi ve SQL enjeksiyonlarına karşı koruma sağlanması gerekir. SQL Server için bir örnek:
DECLARE @select_fields nvarchar(max) = N'müşteri_id, yıl'; DECLARE @agg_fields nvarchar(max) = N'SUM(tutar) AS toplam, COUNT(*) AS satır_sayısı'; DECLARE @group_by nvarchar(max) = N'müşteri_id, yıl'; DECLARE @sql nvarchar(max) = N'SELECT ' + @select_fields + ', ' + @agg_fields + N' FROM satış WHERE satış_tarihi >= @başlangıç AND satış_tarihi <= @bitiş GROUP BY ' + @group_by; EXEC sp_executesql @sql, N'@başlangıç DATE, @bitiş DATE', @başlangıç='2023-01-01', @bitiş='2023-12-31';
Ana özellikler:
Dinamik SQL yerine, tüm muhtemel gruplamalar için tek bir evrensel sorgu oluşturulamaz mı?
Hayır, CASE, SELECT içinde hesaplamalar yapmaya olanak tanır, ancak dinamik olarak belirlenen alanlar için GROUP BY oluşturamaz - bunları yine de açıkça belirtmek gerekir. Statik yaklaşım, canlı BI analitiği için çok kısıtlayıcıdır.
Dinamik olarak WHERE oluştururken SQL sorgusu parametreleri kullanılmalı mı yoksa değerler doğrudan metin içine yerleştirilebilir mi?
Her zaman parametreler kullanın (örneğin, sp_executesql aracılığıyla), aksi takdirde SQL enjeksiyon açığına sahip olursunuz ve korunan değerler (örneğin, dizilerdeki kesme işaretleri) yanlış işlenir.
Tüm muhtemel alan kombinasyonları için bir indeks oluşturmak herhangi bir raporu hızlandırır mı?
Hayır, on binlerce alanı kapsayan bir bileşik dizin oluşturmak, indeks boyutunu büyütür ve ekleme/güncelleme hızını düşürür, bu arada sadece sınırlı sayıda senaryoyu hızlandırır. Sadece gerçekten gerekli olan alanlar/gruplar indekslenmelidir.
Eski bir BI raporunda, uygulamada if-else ile "sert" bir şekilde 30 gruplama varyasyonu kodlandı. Her yeni parametre, kaynak kodunu ve indeks şemasını güncellemeyi gerektiriyordu. Artılar:
Eksiler:
Dinamik SQL kullanarak anlık olarak select/group by oluşturuldu, SQL kodu ayrı bir modülde, parametreler kesinlikle kaçış karakteri ile işlendi. Yeni alanların eklenmesi — basit bir referans ayarı, indeksler filtreleme sıklığına göre ekleniyor. Artılar:
Eksiler: