Neden düzenli döngüler yerine açık imleçler kullanılmalı?


12

Bir yıldır (bir Oracle db için) temel web uygulamaları yazıyorum ve işlevler oldukça basit olduğundan, çoğumuz verilerimizi almak için düzenli FOR döngülerine bağlı kalıyoruz:

for i in (select * from STUDENTS) loop
      htp.prn(i.student_last_name || ', ' || i.student_first_name || ' ' || i.student_dob);
end loop;

Ancak, imleçler işleri yapmanın 'doğru' yolu gibi görünmektedir. İmleçlerin ne olduğu ve bunlarla döngü kurmanın farklı yolları hakkında birçok bilgi bulabilirim, ancak bunları düzenli FOR döngülerinde kullanmanın sağlam bir nedenini bulamıyorum. Prosedürün gereksinimlerine bağlı mı? Bilmem gereken doğal avantajlar var mı?


Bu tür FORimleçleri kullanmanın başka bir yoludur. Dokümanlara bakın: docs.oracle.com/cd/E11882_01/appdev.112/e10472/… Her neyse, htp.prn () ne yapar?
dezso

Bu bizim çıktı fonksiyonlarımızdan biri. Hangi yöntemi kullanacağınıza dair bir tercihiniz var mı?
ini

Bu tür şeyler için FORdöngü çok daha okunaklı olduğunu düşünüyorum. 'Gerçek' imleçleri yalnızca ileriye doğru değil, geriye doğru adım atmam gerektiğinde kullanma eğilimindeyim. Başka bir soru sordum çünkü bunun yerine bir tablo fonksiyonu hayal edebiliyorum htp.prn().
dezso

Her iki imleç biçiminin de saf bir SQL çözümüne göre daha düşük performansa sahip olduğunu, özellikle DML ifadeleriyle ilgili olduğunu belirtmek gerekir.
David Aldridge

Yanıtlar:


7

Bir imleç açık veya kapalı olabilir ve her iki tür de bir FOR döngüsünde kullanılabilir. Sorunuzun gerçekten iki yönü var.

  1. Neden örtülü bir imleç FOR döngüsü üzerinde açık bir imleç FOR döngüsü kullanıyorsunuz?

    • Sorgu yeniden kullanılacaksa açık bir imleç FOR döngüsü kullanın, aksi takdirde örtük bir imleç tercih edilir.
  2. Neden açık bir FETCH olmayan bir FOR döngüsü yerine FETCH ile bir döngü kullanmalıyım?

    • Toplu olarak toplamanız gerektiğinde veya dinamik SQL'e ihtiyacınız olduğunda bir döngü içinde FETCH kullanın.

Belgelerden bazı faydalı bilgiler.

LOOP İÇİN Örtülü İmleç Örneği

BEGIN
   FOR vItems IN (
      SELECT last_name
      FROM employees
      WHERE manager_id > 120
      ORDER BY last_name
   ) 
   LOOP
      DBMS_OUTPUT.PUT_LINE ('Name = ' || vItems.last_name);
   END LOOP;
END;
/

Açık Döngü FOR LOOP Örneği

DECLARE
   CURSOR c1 IS
      SELECT last_name
      FROM employees
      WHERE manager_id > 120
      ORDER BY last_name;
BEGIN
   FOR vItems IN c1 LOOP
      DBMS_OUTPUT.PUT_LINE ('Name = ' || vItems.last_name);
   END LOOP;
END;
/

Örtük İmleç

Örtük bir imleç PL / SQL tarafından oluşturulan ve yönetilen bir oturum imlecidir. PL / SQL, SELECT veya DML deyimlerini her çalıştırdığınızda örtük bir imleç açar. Örtük bir imleci denetleyemezsiniz, ancak özniteliklerinden bilgi alabilirsiniz.

Örtük bir imleç ilişkili ifadesi çalıştıktan sonra kapanır; ancak, özellik değerleri başka bir SELECT veya DML ifadesi çalışana kadar kullanılabilir durumda kalır.

Örtük imleç öznitelikleri şunlardır: SQL% ISOPEN, SQL% FOUND, SQL% NOTFOUND, SQL% ROWCOUNT, SQL% BULK_ROWCOUNT, SQL% BULK_EXCEPTIONS

Açık İmleç

Açık bir imleç, oluşturup yönettiğiniz bir oturum imlecidir. Açık bir imleci tanımlayıp tanımlamanız, ona bir ad vermeniz ve bir sorgu ile ilişkilendirmeniz gerekir (genellikle, sorgu birden çok satır döndürür). Daha sonra sorgu sonuç kümesini aşağıdaki yollardan biriyle işleyebilirsiniz:

Açık imleci (OPEN deyimi ile) açın, sonuç kümesinden satırları getirin (FETCH deyimi ile) ve açık imleci kapatın (CLOSE deyimi ile).

Bir imleç FOR LOOP deyiminde açık imleci kullanın (bkz. "LOOP İfadeleri İçin İmleç ile Sorgu Sonuç Kümesi İşleme").

Açık bir imlece değer atayamaz, bunu bir ifadede kullanamaz veya resmi bir alt program parametresi veya ana bilgisayar değişkeni olarak kullanamazsınız. Bunları bir imleç değişkeni ile yapabilirsiniz (bkz. "İmleç Değişkenleri").

Örtük bir imlecin aksine, açık bir imleç veya imleç değişkenine adıyla başvurabilirsiniz. Bu nedenle, açık bir imleç veya imleç değişkenine adlandırılmış imleç denir.

LOOP İfadeleri İÇİN İmleç

İmleç FOR LOOP deyimi, bir SELECT deyimi çalıştırmanıza ve ardından hemen sonuç kümesinin satırları arasında geçiş yapmanıza olanak tanır. Bu ifade örtük veya açık bir imleç kullanabilir.


1
Örtük imleçler, 10g'den itibaren bir seferde 100 satır getirir.
David Aldridge

16

Gönderdiğiniz kod bir imleç kullanıyor. Kapalı bir imleç döngüsü kullanıyor.

Açık bir imleç döngüsü kullanmanın (yani bildirim bölümünde bir CURSOR değişkenini bildirme) ya daha temiz kod ya da daha iyi performans ürettiği durumlar vardır

  1. Görünümlere yeniden bakamayacağınız daha karmaşık sorgularınız varsa, döngünüz tekrarlanırsa kodun okunmasını kolaylaştırabilir student_cursorbir grup mantığı gömen 30 satırlık bir SQL ifadesi eklemek yerine. Örneğin, mezun olması için temizlenmiş ve akademik kayıtları olan masalara, lisans programlarının gerekliliklerine, akademik ambarlarla ilgili bilgi içeren masalara, gecikmiş kütüphane kitapları hakkında bilgi içeren masalara, ödenmemiş ücretler, yönetimsel geçersiz kılmalar, vb. hakkında bilgi içeren tablolar, bu sorgunun listeyi bir kullanıcıya sunmasıyla ilgili kodun ortasında sıkışmaması için muhtemelen kodu yeniden düzenlemek mantıklı olacaktır. Bu, tüm bu mantığı çevreleyecek bir görünüm oluşturmayı içerebilir. Veya geçerli PL / SQL bloğunun bir parçası olarak veya daha üst düzey bir PL / SQL bloğunda (ör. pakette bildirilen bir imleç) yeniden kullanılabilir olması için. Veya kapsülleme ve yeniden kullanılabilirlik için başka bir şey yapmayı da içerebilir (örneğin, bunun yerine bir boru hattı tablosu işlevi oluşturma).
  2. PL / SQL'de toplu işlemlerden yararlanmak istiyorsanız, genellikle açık imleçler kullanmak istersiniz. İşte açık ve kapalı imleçler arasındaki performans farklarını tartışan bir StackOverflow iş parçacığı . Yaptığınız tek şey aramaksa htp.prn, BULK COLLECTmuhtemelen bir şey satın almazsınız. Bununla birlikte, diğer durumlarda, önemli performans iyileştirmeleriyle sonuçlanabilir.

2

Birçok geliştiricinin eski alışkanlıktan örtük imleçler yerine açık imleçler kullandığını görüyorum. Çünkü Oracle sürüm 7'de bu her zaman daha etkili bir yol oldu. Günümüzde genellikle başka bir yol var. Özellikle optimize edici ile gerekirse bir toplu toplama döngüler için örtük imleci yeniden yazabilirsiniz.


0

Son zamanlarda bir grup sorgu örtülü FOR döngü açık imleçler içine yeniden yazmak zorunda kaldı. Bunun nedeni, sorguların bağlantı yoluyla harici bir veritabanından veri alması ve bu veritabanının yerel veritabanımızdan farklı bir kodlamaya sahip olmasıdır. Örtük imleçten yerel olarak tanımlanmış bir kayıt türüne veri aktarılırken gizemli aralıklı hatalar oluştu (yalnızca belirli satırlarda). DBA'mız bunu bize açıkladı, biz bunun alt kısmına kendimiz ulaşamazdık. Görünüşe göre bu Oracle'da bildirilen bir hata.

Açık imleçleri kullanarak her şeyi yeniden yazmanız tavsiye edildi ve hata gitti.

Açık bir şekilde örtük olarak kullanmak isteyebileceğiniz birincil neden değil, bir nota değer.

EDIT: Oracle 12c.


Hata ve / veya not numarasını ekleyebilir misiniz?
Leigh Riffel

Maalesef hata bildirimi DBA'larımızdan biri tarafından yapıldı, bu bilgilere erişimim yok.
Robotron
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.