plsql

PL/SQL Komut Satırında Çıktı (Sonuç) Görüntülemek

Oracle veritabanı kullanıcısıysanız PL/SQL komut satırında (Command Line) bazı sonuçları görüntülemek isteyebilirsiniz. Bunun için dbms_output.put_line() fonksiyonu kullanılır.

Bazı araçlarda bu fonksiyonu kullandığımız halde sonuç görüntülenmeyebilir. Bu durumda serveroutput değişkenine on değerini atamamız gerekir.

SQL> set serveroutput on

Örneğin bir prosedür sonucunda "hosaf.org" yazdırmak istersek aşağıdaki şekilde yazmamız gerekecektir;

SQL> set serveroutput on
SQL> declare
  2    v_line varchar2(40);
  3  begin
  4    v_line := 'hosaf.org';
  5    dbms_output.put_line (v_line);
  6  end;
  7  /

hosaf.org
 
PL/SQL procedure successfully completed.

Bilgi kaynağı: http://www.dba-oracle.com/concepts/displaying_pl_sql_output.htm

Oracle'da (PL/SQL) Bir Satırın Varlık Bilgisini Alma İpucu

Bir veritabanı kaydının sadece varlığıyla yani olup olmadığıyla ilgileniyorsak ilk akla gelen strateji, count(*) yani kayıt sayısını alıp bu değerin sıfırdan büyük olup olmaması karşılaştırmasını yapmak.

KISI tablosunda GRUP alanı 1 olan kayıt var mı diye merak ettik diyelim.

select count(*) from KISI k where k.GRUP=1

Bu sorgu eğer KISI tablosunda GRUP alanı 1 olan çok fazla kayıt varsa uzun sürecektir. Halbuki biz sadece varlığını merak ettiğimiz için gereksizce beklemiş olma ihtimalimiz var.

Bu durumu çözmek için rownum anahtar kelimesini kullanabiliriz. rownum ile sorguyu daha da kısıtlayarak belli bir satır numarasından fazlasını almamayı sağlayabiliriz. Yani satır numarası 1 olan kaydın sayısını (count(*)) where koşulunda rownum=1 ile kısıtlayarak çekersek en az bir tane bu tipte kayıt olduğunu ya da hiç olmadığını anlayabiliriz;

select count(*) from KISI k where k.GRUP=1 and rownum=1

Bu sorgu sonucunda elimize ya 0 ya da 1 değeri gelecektir. 0 olduğunda herhangi bir kayıt sayılmamış yani hiç bu koşula uygun kayıt yok demektir. 1 ise belki birden fazla vardır fakat en azından bir tane bu koşula uygun kayıt vardır demektir. İlgilendiğimiz bilgi varlık olduğundan bu sorgu büyük kayıtlara sahip olabilecek tablolarda daha hızlı cevap verecektir.

Kaynak: https://stackoverflow.com/questions/1088156/quickest-query-to-check-for-...

Oracle DB Notları

Oracle veritabanı ile ilgili notlarımı burada paylaşıyorum.

Oracle'da (PL/SQL) Grant

Konumuz kırk yılın başı kullandığımızdan unutmuş olabileceğimiz şeyler kategorisindeki grant

Kullanım şekli:

grant privileges on object to user;

privilegesolarak anılan yerde olabilecekler:
select, insert, update, delete, references, alter, index

Kaynak: http://www.techonthenet.com/oracle/grant_revoke.php

Oracle'da (PL/SQL) Bind Variable'ın Önemi ya da Hard Parse, Soft Parse Olayları

Birkaç yıldır Oracle veritabanı kullanıcısı olmama ve hatta Java'da diğer veritabanlarıyla da çalışmış olmama rağmen atladığım önemli noktalardan biri 'Bind Variable' konusu. (Bu arada bkz: variable kelimesinin telaffuzu)

SQL sorgularını normal şartlarda bildik biçimde, basitçe şöyle yazıyoruz:

SELECT ad, soyad, telefon, adres FROM kisi WHERE id = 100;

Oracle bu sorguyu görünce daha önce bu sorgu yapılmış mı diye shared pool'unu kontrol ediyor. Yoksa bu sorguyu execute ediyor, ya da başka bir deyişle execution plan oluşturuyor. Sorgunun yazım doğruluğunu kontrol ediyor, yazımı doğruysa gerçekten makul bir sorgu olup olmadığını kontrol ediyor. Bu işleme 'Hard Parse' da deniyor. Hard parse olayında CPU kullanımı artıyor.

Eğer shared pool'da bu sorgu varsa, yani daha önce bu sorgu aynen yapılmışsa, daha önce kullanılmış olan execution plan'ı kullanıyor dolayısıyla maliyetten (cost) kazanıyor. Bu örnekte her bir kişi sorgusu için ayrı ayrı id'ler vermemiz gerekiyor. Bu da her bir sorgu için ayrı bir execution plan oluşturması demek. Bunun yerine değişen id alanımızı bir 'Bind Variable' haline getirebiliriz:

SELECT ad, soyad, telefon, adres FROM kisi WHERE id = :kisi_id ;

Daha önceki sorguda doğrudan 100 olarak belirttiğimiz id sütununu burada kisi_id adlı değişken olarak veriyoruz ve sorgunun yanında 100 değerini parametre olarak gönderiyoruz. SQL*Plus gibi bir uygulama içinde şu şekilde parametreleri kullanıyoruz:

SQL> variable kisi_id number
SQL> exec :kisi_id := 674
PL/SQL procedure successfully completed.

SQL> SELECT ad, soyad, telefon, adres FROM kisi WHERE id = :kisi_id;

Burada kullandığımız :kisi_id yazının başlığında bahsettiğimiz bind variable oluyor.

Pek iyi ama biz geliştiriciler olarak sorguları aslında bu şekilde yapmıyoruz. Uygulamamız içinde sorguları veriyoruz ve uygulama anında bu sorgular çalıştırılıyor. O halde ne olacak? Bu durum Java ve .NET için Prepared Statement tarzı yaklaşımlar ile çözülüyor. (Diğer dilleri bilmiyorum ama benzer şeyler olduğunu farklı kaynaklarda okuyoruz.)

Artık ORM kullandığımız için sorguları da doğrudan yazmıyor olabiliriz. Hibernate'i örnek alırsak; bizim için prepared statement yaklaşımını zaten benimsemiş durumda olduğundan yapmamız gereken şey Query'lere bind variable yazdıktan sonra query objesine parametre set etmek;

Query q = session.createQuery("from Kisi where id = :kisi_id");
q.setParameter("kisi_id",100);

Bir diğer kullanım şekli ise değişken yerine soru işareti koyduktan sonra, ilgili querylere doğrudan parametre set etmek ya da -HibernateTemplate kullanıyorsak- HQL ya da doğrudan SQL sorgusunu kullanan metodun ikizi niteliğindeki aynı isimli diğer metodu kullanmak. Örneğin;

Query q = session.createQuery("from Kisi where id = ?");
q.setParameter(0,100);

ya da HibernateTemplate kullanımı;

getHibernateTemplate().find("from Kisi where id = ?", 100);

ya da birden fazla parametre için;

getHibernateTemplate().find("from Kisi where id = ? and ad = ?", new Object[]{100,"Yasin"});

Bu konunun bir de güvenlik yönü var. Kısaca: "bind variable kullanın, güvenliğinizi arttırın" diyor. Kaynaklarda geçen makaleleri okursanız detayları keşfedebilirsiniz.

Kaynaklar:

Subscribe to RSS - plsql