ORACLE NVL FONKSIYONU

Veritabanımızdaki integer bir sütun, not null constraint`i ile tanımlanmamışsa boş olarak kaydedilebilir. Fakat biz bu alandaki değerin de içinde bulunduğu bir toplama işlemi yapmak istersek işlemin çıktısını boş olarak görürüz. Yapmamız gereken ise bu alandaki null değeri başka bir değerle değiştirmek. Eğer toplama işleminin sonucunu değiştirmek istemiyorsak değiştireceğimiz değerin `0` olması gerekmektedir.
NVL fonksiyonu null bir değeri başka bir değerle değiştirir.

Örnek olarak;

select id, urun_isim, son_kullanma_tarihi, bonus, fiyat+nvl(kdv,0);

Burada kdv değeri null olarak gelse bile onu “0″ değerine çevirir ve işlem için hata olmasını engeller. İsteseydik “0″ yerine başka bir değerde atayabilirdik.

Sorgu sonucu istediğimiz şekilde hatasız olarak değer döndürür. Bu sayede null olma sebebiyle oluşabilecek hataların önüne geçilmiş olduk.
spacer

ORACLE DECODE FONKSIYONU KULLANIMI

Oracle/PLSQL de if yapısını biliyorsunuzdur.If yapısının yaptığı işin benzerini yapar.Select sorgularımızda istediğimiz koşula göre verileri gösterme işine yarar.If yapısı daha çok prosedürel kod kısmında kullanılırken bu fonksiyon select de kullanılır.

Örneğin id alanına göre id değeri 1 ise şunu göstersin 2 ise şunu göstersin gibi bir örnek yapalım.



select student_name,
decode(id,1,’Birinci Sinif’,
2,’İkinci Sinif’,
‘mezun’) decode_kolonu
from student_table;



Örnekteki id kolon değeri 1 durumunda decode_kolonu Birinci Sinif, id değeri 2 ise İkinci Sinif ve diğer durumlar için de mezun stringi gösterilmiştir.

Bunun if yapısına göre karşılığı şöyledir.

İf(id==1) then

{

decode_kolonu:=”Birinci Sinif”;

}

elsif(id==2) then

{

decode_kolonu:=”İkinci Sinif”;

}

else

{

decode_kolonu:=”mezun”;

}

end if;



Yukarıdaki örnekte sadece id değeri için tek değer kontrolü yapılmaktadır.Diyelim ki id alanı 1 ile 10 arası olanlar kategori1 10 ile 20 arası olanlar kategori2 ve diğer durumlar için kategori3 olsaydı nasıl yapacaktık.Bir nevi tek koşul yerine iki koşul olsaydı durum nasıl olurdu?

select
decode(trunc(id/10),0,’kategori1′,
1,’kategori2′,
‘kategori3′) decode_kolonu
from bölümler;

Örnekte id alanı örneğin 8 ise 8/10 bize 0.8 değerini üretecek trunc fonksiyonuda bu arada söyleyelim ki kesme işlemi yapar noktadan sonrasını atar tam sayıyı döndürür bize yani sonuç 0 olur.0 ise ketagori1 olur.Bir diğer örnek 17 değeri olsun.bu değer 1.7 ve trunc(1.7) ile de 1 sonucunu üretir.yani kategori2 olmuş olur.Bu şekilde ister 10 ar 10 ar ister kendi istediğiniz değere göre aralık belirleyebiliriz.Bunun if kodu ise şöyledir.

if(id<10 and id>=0) then

{

decode_kolonu:=”kategori1″;

}

elsif(id<20 and id>=10) then

{

decode_kolonu:=”kategori2″;

}

else

{

decode_kolonu:=”kategori3″;

}

end if;
spacer

ORACLE PARTITION-SUBPARTITION

Tabloların boyutları büyüdükçe yapılacak olan select,insert,update gibi işlemler yavaşlar.Bir tablodaki veriler gigabyte seviyesine kadar gelir belki de daha fazla.İşte bu gibi durumlarda o tabloyu belli özelliklere göre partition yani bölümlere ayırırız.Ve böylece artık işlemlerimizi çok daha hızlı yaparız.Partitionların bir diğer güzel yanı Oracle’ın bize istediğimiz partition’u istediğimiz tablespace’e taşımamıza yada istediğimiz yerde yaratmamıza izin veriyor olmasıdır.Zaten burda amaç bir tablespace çok fazla veri ile dolduğu zaman yeni kayıt yeri olmaması ve bu verileri başka yere taşımaktır.Örneğin ilk bilgisayar sistemlerine geçildiği zaman herkesin kütük bilgileri yani TC Kimlik Numarasına göre basit kayıtların yapıldığını düşünelim.Zamanla bu tablo o kadar büyüyecekki herkesin kaydı oraya alıcak ve hergeçen gün de artmaya devam edecek.Bir süre sonra tablo üzerinde insert,select işlemi gibi işlemler çok yavaşlayacak.Hele ki diğer kurumlarda bu tablodan TC Kimlik No ya ulaşığ işlemleri buna göre yapıyorlarsa işte size partition ve subpartition :) Yıllara göre partition yapsak bu yavaşlıktan kurtuluruz.



Range Partition: Belirli bir limit aralığı

Hash Partition: Hash fonksiyonunun ürettiği sonuca göre

List Partition: Belli bir liste yaparak o liste baz alınarak yapılan partition

Range-Hash Partition: Range’e göre partition ve Hash’e göre subpartition

Range-List Partition: Range göre partition ve List’e göre subpartition



Evet örneğe geçmeden bir tablo içinde veri olmadan partition yapılmalıdır ki veriler o partition’a göre kaydedilsin.Ve eğer içi veri dolu bir tabloya partition yapmak istiyorsanız şu adımları izlemelisiniz.

1-Partition yapılmak istenen tabloyla eşdeğer fakat farklı isimde bir tablo yaratmak

2-Yaratılan tabloya partition yapmak

3-Verileri eski tablodan yeni yani partitionlu tabloya taşımak

4-Eski tabloyu silmek

5-Yeni tablonun adını eski tablonun adı olarak değiştirmek



Şimdi Range partitiona örnek verelim.Doğum tarihe göre partition yapacak olursak;



PARTITION BY RANGE(DOGUM_TARIHI)

(

PARTITION DOGUM_TARIHI_1990DAN_KUCUK VALUES LESS THAN(TO_DATE(’01.01.1990′,’DD.MM.YYYY’)),

PARTITION DOGUM_TARIHI_2000DEN_KUCUK VALUES LESS THAN(TO_DATE(’01.01.2000′,’DD.MM.YYYY’)),

PARTITION DOGUM_TARIHI_2010DAN_KUCUK VALUES LESS THAN(TO_DATE(’01.01.2010′,’DD.MM.YYYY’)),

PARTITION DOGUM_TARIHI_2010DAN_BUYUK VALUES LESS THAN(MAXVALUE)

);



Evet Doğum Tarihine göre tablomuzu partitionlara böldük.Burada özel bir MAXVALUE anahtarını kullandık ki bu en büyük kayıt aralığını tutuyor.Kayıt olmayan bir alana denk gelip Oracle hata vermesin diye.Diyelim ki 2010 yılından büyük kaç kayıt olduğunu öğrenmek istiyoruz.Biz biliyoruz ki Doğum Tarihi 2010 yılından büyük olan kişiler DOGUM_TARIHI_2010DAN_BUYUK partitionunda kayıtlı.



SELECT COUNT(TC_KIMLIK_NO) FROM KISILER PARTITION (DOGUM_TARIHI_2010DAN_BUYUK);



Yukarıdaki sorgu ile Tablodaki 4 partition dan sadece 1 tane si üzerinde sorgu yürütülecek ve sonuçları bize getirecektir.Eğer partition olmasaydı bütün tablo üzerinde sorgu yürütülecekti.Mesela ülkemizde Doğum Tarihi 2010′dan küçük 70 milyon ve 2010′dan büyük 2 milyon insan olsun.Böyle bir sorgu ile 72 milyon kayıt yerine 2 milyon kayıt üzerinde sorgumuz çalışacaktır ve bu bize yüksek performans ve düşük zamandan kazandıracaktır.



Bir de List partitiona örnek yazalım.Diyelim ki her kayıt için Erkek ve Kadın diye Cinsiyet tutulsun.İşte biz de bu sefer cinsiyete göre listeli partition yapacağız.



PARTITION BY LIST(CINSIYET)

(

PARTITION ERKEK_LISTESI VALUES(‘ERKEK’),

PARTITION KIZ_LISTESI VALUES(‘KADIN’)

);



Bazen partitionlarda da çok fazla veri olur.Ve çözüm olarak da subpartition gerekir :)

Örnek olması açısından yukarıdaki örnekleri birleştirerek Range-List partition yapmış oluru.Yani Range partition List Subpartition olmuş olur.



PARTITION BY RANGE(DOGUM_TARIHI)

PARTITION BY LIST(CINSIYET)

(PARTITION DOGUM_TARIHI_2010DAN_KUCUK VALUES LESS THAN(TO_DATE(’01.01.2010′,’DD.MM.YYYY’))

(

SUBPARTITION ERKEK_LISTESI VALUES(‘ERKEK’),

SUBPARTITION KIZ_LISTESI VALUES(‘KADIN’)

)

(PARTITION DOGUM_TARIHI_2010DAN_BUYUK VALUES LESS THAN((MAXVALUE)))

(

SUBPARTITION ERKEK_LISTESI VALUES(‘ERKEK’),

SUBPARTITION KIZ_LISTESI VALUES(‘KADIN’)

);



Sistemdeki tüm partitonları görmek için;



SELECT * FROM ALL_TAB_PARTITIONS;



Kullanıcıya ait partitionları görmek için;



SELECT * FROM USER_TAB_PARTITIONS;



İle partitionların hangi tablo ya ait olduğunu hangi tablespace de olduğunu ayrıntılı olarak görebilirsiniz.

Bir tabloya ait partitionları görmek için ise;



SELECT * FROM USER_TAB_PARTITIONS WHERE TABLE_NAME LIKE ‘KISILER’ ;
spacer

ORACLE CASE YAPISI

Case ifadesi if-then-else ifadesinin başka bir alternatifidir.Kullanım şekli :

CASE [ ifade]
WHEN durum1 THEN sonuc1
WHEN durum1 THEN sonuc2

WHEN drumn THEN sonucn
ELSE baskasonuc
END

Ifade ve else alanı zorunlu değildir, isteğe bağlıdır.Oracle burda 255 tane koşula kadar izin verir.Hangi WHEN….THEN koşulu geçerli ise ona göre sonuc return edilir.Hiçbir koşul gerçekleşmezse NULL döndürülür.



select table_name,
CASE owner
WHEN ‘SYS’ THEN ‘The owner is SYS’
WHEN ‘SYSTEM’ THEN ‘The owner is SYSTEM’
ELSE ‘The owner is another value’
END
from all_tables;

select table_name,
CASE
WHEN owner=’SYS’ THEN ‘The owner is SYS’
WHEN owner=’SYSTEM’ THEN ‘The owner is SYSTEM’
ELSE ‘The owner is another value’
END
from all_tables;

Aşağıdaki, yukardaki 2 örneğin if-then-else yapısıdır.

IF owner = ‘SYS’ THEN
result := ‘The owner is SYS’;

ELSIF owner = ‘SYSTEM’ THEN
result := ‘The owner is SYSTEM”;

ELSE
result := ‘The owner is another value’;

END IF;

Örnekler:

select table_name,
CASE owner
WHEN ‘SYS’ THEN ‘The owner is SYS’
WHEN ‘SYSTEM’ THEN ‘The owner is SYSTEM’
END
from all_tables;



select
CASE
WHEN a < b THEN ‘hello’
WHEN d < e THEN ‘goodbye’
END
from suppliers;

İki koşul için case kullanımı örneği:

select supplier_id,
CASE
WHEN supplier_name = ‘IBM’ and supplier_type = ‘Hardware’ THEN ‘North office’
WHEN supplier_name = ‘IBM’ and supplier_type = ‘Software’ THEN ‘South office’
END
from suppliers;
spacer

ORACLE SUBSTR FONKSIYONU

Bir string üzerinden başka bir stringi elde etmemizi sağlar.

substr( string, start_position, [ length ] )

string olan baz alınacak kaynak stringdir.start_position elde edilecek string için stringin hangi karakterinden başlanacağıdır.Eğer pozitif ise sol baştan negatif ise sağ baştan alır.length alanı ise o karakterden itibaren kaç karakter alınacağıdır.length alanı zorunlu değildir.girilmezse başlangıçtan itibaren tüm string alınır.

select substr(‘ABDULAH’,2,3) from dual;

sorgusu geriye BDU döndürür.

select substr(‘ABDULAH’,3) from dual;

sorgusu DULAH döndürür.

select substr(‘ABDULAH’,-2) from dual;

sorgusu AH döndürür.

select substr(‘ABDULAH’,4,-2) from dual;

Eğer length değeri negatif olursa geriye NULL döndürülür.
spacer

ORACLE GRANT-REVOKE

Oracle da kullanıcılara select,insert,update,delete,reference,alter ve index gibi yetkileri vermek için Grant verilen yetkileri almak için de Revoke kullanılır.

GRANT yetkiler ON nesne TO kullanıcı;

Örneğin Abdullah kullanıcısına müşteriler tablosu için select, insert, update, delete yetkisi vermek istiyorum.

GRANT select, insert, update, delete ON musteriler TO Abdullah;

Yetki alanı için Abdullah kullanıcısı için kısıt koymazsak yani bütün yetkileri vermek istersek;

GRANT all ON musteriler TO Abdullah;

Birde bir yetkiyi tüm kullanıcılara vermek istersek yani kullanıcı bazlı kısıt koymazsak;Örneğin select yetkisi:

GRANT select ON musteriler TO public;

Tablo üzerindeki yetkiyi almak istersek:

REVOKE select,delete ON musteriler FROM Abdullah;

Abdullah kullanıcısının musteriler tablosu için tüm yetkilerini almak istersek;

REVOKE all ON musteriler FROM Abdullah;

Ve son olarak musteriler tablosu için tüm kullanıcılar için tüm yetkileri almak istersek;

REVOKE all ON musteriler FROM public;

Fonksiyon ve procedure için yetki vermek yada almak istersek EXECUTE kullanırız.myfunction adında fonksiyon işlemleri için:

GRANT execute ON nesne TO kullanıcı;

GRANT execute ON myfunction TO Abdullah;

GRANT execute ON myfunction TO public;

REVOKE execute ON nesne FROM kullanıcı;

REVOKE execute ON myfunction FROM Abdullah;

REVOKE execute ON myfunction FROM public;
spacer

ORACLE SEQUENCE(OTOMATIK SAYI)

Oracle da access yada Ms sql dekine benzer otomatik arttırma diye birşey yoktur.Bunu yapmak için siz kendiniz sequences yaratmalısınız.

CREATE SEQUENCE sequence_name
MINVALUE value
MAXVALUE value
START WITH value
INCREMENT BY value
CACHE value;

Örneğin:

CREATE SEQUENCE supplier_seq
MINVALUE 1
MAXVALUE 999999999999999999999999999
START WITH 1
INCREMENT BY 1
CACHE 20;

Burada MINVALUE en küçük MAXVALUE en büyük değer koşuludur.MAXVALUE zorunlu değildir.Atanmazsa varsayılan olarak 999999999999999999999999999 değerini alır.START WITH başlangıç değerini INCREMENT BY her seferinde ne kadarlık bir değer artışı olacağını gösterir.CACHE ise sequnece işleminin performans açısından daha hızlı olması için bellekte tutulacak değerdir.NOCACHE bellekte tutulmayacağı demektir.Sequencesin bir sonraki değerine ulaşmak için sequence_name.nextval ile erişilebilir.

INSERT INTO musteriler
(musteri_id, musteri_name)
VALUES
(supplier_seq.nextval, ‘Ali Çetinkaya’);

Normalde değerler Increment By da belirtilen kadar artar mesela diyelim ki bu değer 1 olsun ve son kullanılan değer 100 olsun. Biz bir sonraki insert işleminde 255 atamak istiyorsan Alter ifadesi ile sequence i değiştirmemiz gerekir.

alter sequence seq_name
increment by 124;

select seq_name.nextval from dual;

alter sequence seq_name
increment by 1;

Böylece bir sonraki değer 255 olacak ve sonra yine 1 artacaktır.
spacer