ProgramlamaSQL Geliştirici

SQL'de kursör (CURSOR) kullanarak seri veri işleme özelliklerini, avantajlarını ve tehlikelerini açıklar mısınız? Kursörlerin ne zaman kullanılması mantıklıdır ve ne zaman set-based (set bazlı) işlemler lehine kaçınılmalıdır? Kursör kullanımına bir örnek verin.

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

Cevap.

Kursörler SQL'de veri kümesini satır satır gezmeyi ve her kayıtta belirli işlemleri gerçekleştirmeyi sağlar; bu, programlamada yineleme gibi bir şeydir. Bu, bir SQL tek sorgusuyla gerçekleştirilemeyen karmaşık adım adım mantık için kullanışlıdır (örneğin, dış durumu değiştiren adım hesabı).

Kursör örneği:

DECLARE my_cursor CURSOR FOR SELECT id, balance FROM Accounts WHERE isActive = 1; OPEN my_cursor; DECLARE @id INT, @bal DECIMAL(10,2); FETCH NEXT FROM my_cursor INTO @id, @bal; WHILE @@FETCH_STATUS = 0 BEGIN UPDATE Accounts SET balance = @bal * 1.05 WHERE id = @id; FETCH NEXT FROM my_cursor INTO @id, @bal; END CLOSE my_cursor; DEALLOCATE my_cursor;

Avantajları:

  • Her satırın ayrı bir işlem veya dış koşul kontrolü gerektirdiği karmaşık prosedürlerin gerçekleştirilmesine olanak tanır.
  • Adım adım kontrol gerektiren eski sistemlerle veya göçlerle entegrasyon için uygundur.

Dezavantajlar ve tehlikeler:

  • Kursörler genellikle ÇOK yavaştır: işlem satır bazında yapılır, set bazında değil;
  • Çok fazla kaynak tüketir, tablolara kilitlenebilir;
  • Büyük veri hacimleri için ölçeklenemez;
  • Set-based SQL ile yeniden yazılması veya toplu işlem kullanılması daha iyidir.

Şartlı Soru.

Kursör bir tetikleyici içinde kullanılabilir mi? Bunun veritabanı performansı üzerinde ne gibi sonuçları olabilir?

Cevap ve örnek: Kursörün bir tetikleyici içinde kullanılması mümkündür, ancak şiddetle tavsiye edilmez - her DML işlemi ilgili her satır için bir kursör başlatabilir, bu da sorguların ve kilitlerin avcı gibi artmasına neden olur.

CREATE TRIGGER UpdateBalance ON Accounts AFTER INSERT AS DECLARE c CURSOR FOR SELECT id FROM inserted; -- kötü! OPEN c; -- ...

Hikaye

Proje: Perakende Sipariş Özeti. Stokta kalanları hesaplamak gerekiyordu, partide bir hata bulunursa - sonraki partilerin manuel olarak indirim güncellemeleri ile yeniden hesaplanması gerekiyordu. Partileri döngüyle gezmek için kursör kullanıldı. Daha sonra, sık sık çalıştırmalarda akışın saatlerce kilitlenmesi, sunucu üzerindeki yükün üssel olarak artması ve kilit çatışmalarının arızalara yol açtığı anlaşıldı.


Hikaye

Proje: ERP, veri göçü. İçe aktarma işlemi sırasında hata işleme için kursör ekledik. 5 milyon satırda, kursörün set-based UPDATE + CASE ile benzer toplu işlemden 40 kat daha yavaş çalıştığını dikkate almadık. Yavaş göç nedeniyle son tarihler kaydırıldı.


Hikaye

Proje: Finans şirketi Faturalama. Ağ akışını güncelleyen tabloya yeni bir toplam bakiye hesaplamak için kursör ekledik. Bu prodüksiyonda "DÜNYAYI DURDUR" durumuna neden oldu - tek bir kaydın eklenmesi, birçok satır için iç içe geçen bir kursör başlatılması nedeniyle hizmetin çalışmasını yavaşlattı.