ProgramlamaBackend geliştirici

Kullanıcı Tanımlı Fonksiyonlar (UDF) aracılığıyla SQL'de karmaşık iş kuralları ve hesaplamaları nasıl gerçekleştirilir? Skalar UDF ile tablo UDF arasındaki farklar ve kısıtlamalar nelerdir, ne zaman kullanılması daha uygun, ne zaman bu tür bir mantığın dış uygulamada uygulanması daha iyidir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

SQL'de iş mantığını kullanıcı tanımlı fonksiyonlar (User Defined Functions, UDF) aracılığıyla gerçekleştirerek hesaplamaların ve iş kurallarının bir kısmını veritabanına taşımak mümkündür.

Skalar fonksiyonlar tek bir değer döndürür ve ifadelerde çağrılır — örneğin, parametrelere dayanarak bir sonuç hesaplamak için:

CREATE FUNCTION dbo.GetDiscount(@price DECIMAL(10,2), @loyaltyLevel INT) RETURNS DECIMAL(10,2) AS BEGIN RETURN @price * CASE WHEN @loyaltyLevel = 1 THEN 0.95 WHEN @loyaltyLevel = 2 THEN 0.90 ELSE 1.0 END END; -- Kullanım örneği: SELECT Name, dbo.GetDiscount(Price, LoyaltyLevel) AS DiscountPrice FROM Products;

Tablo fonksiyonları bir dizi satır (tablo) döndürür:

CREATE FUNCTION dbo.ActiveOrders(@userId INT) RETURNS TABLE AS RETURN ( SELECT * FROM Orders WHERE UserId = @userId AND Status = 'Active' ); -- Kullanım: SELECT * FROM dbo.ActiveOrders(123);

Farklar, kısıtlamalar ve öneriler:

  • Skalar UDF'ler genellikle büyük seçimlerde düşük performans sergiler, çünkü satır bazında çağrılır;
  • Tablo UDF'ler sorgu planlarına daha iyi entegre olur ve normal tablolar gibi kullanılabilir;
  • Dış kaynaklara erişim veya karmaşık iş işleme gerektiren mantıkları SQL dışına taşımak daha iyidir.

Kandırıcı Soru.

INLINE tablo fonksiyonu ile çoklu ifadeli (multi-statement) tablo fonksiyonu arasındaki fark nedir? Bu seçim performansı nasıl etkiler?

Cevap ve örnek:

  • INLINE fonksiyonu (tek ifadeli, hemen SELECT döndürür) ana sorgunun bir parçası olarak optimize edilir, ek bir tablo oluşturmaz ve daha hızlı çalışır, sorgu planı genel olur.
  • Çoklu ifadeli fonksiyon geçici bir tablo (tablo değişkeni) oluşturur, bu nedenle genellikle sorgu planı daha kötü olur, kardinalite tahmini hataları yaşanabilir ve performans düşebilir.
-- INLINE CREATE FUNCTION dbo.InlineActiveOrders(@userId INT) RETURNS TABLE AS RETURN ( SELECT * FROM Orders WHERE UserId = @userId AND Status = 'Active' ); -- Çoklu İfadeli CREATE FUNCTION dbo.MultiActiveOrders(@userId INT) RETURNS @result TABLE (...) AS BEGIN INSERT INTO @result SELECT ... -- mantık RETURN END

Tarih

Proje: Finansal Analiz. Büyük bir tablo kümesine yönelik rapor sorgusunun select kısmında skalar UDF'ler kullandık: SELECT Amount, dbo.CalcTax(Amount, Type) FROM Transactions. Sorgu, satır bazında UDF işlenmesi nedeniyle 5-10 dakika sürdü. Bunu yerleşik CASE ile yeniden yazdık: süre saniyelere düştü.


Tarih

Proje: E-ticaret. Kullanıcı sepetlerini bulmak için çoklu ifadeli tablo fonksiyonları kullandık, burada birden fazla aşamadan oluşan filtreleme mantığı vardı. SQL'in optimal bir plan oluşturmadığını ve gerektiğinde bile tarama yaptığını gördük. INLINE fonksiyonuna geçiş, sorguları 50 kat hızlandırdı.


Tarih

Proje: CRM. Bonus hesaplama iş mantığını karmaşık bir UDF'ye taşıdık. Birkaç ay sonra iş kurallarının değiştiğini anladık, fakat fonksiyonu güncellemek verilerle olan sıkı bağlantı nedeniyle zordu. İteratif bir üründe UDF, backend ve DB arasında değişiklik koordinasyonu için yüksek maliyetlere sebep oldu.