
Ercan Yazgan
Oracle Technologies Specialist
Website bağlantısı: E-posta: Bu e-Posta adresi istek dışı postalardan korunmaktadır, görüntülüyebilmek için JavaScript etkinleştirilmelidir
Hüsnü Şensoy / DBA of the Year 2009
Selam Arkadaşlar,
Sizlere 2009 yılında dünya çapında yılın dba i seçilen Hüsnü Şensoy' un röportajından bir kesit sunmak istiyorum. Dünyada bu ünvana sahip en genç kişi şu anda kendisi ve bu alanda Türkiye'nin de gururu diyebiliriz. Kendisinin Oracle ve meslek hayatı üzerindeki görüşlerini ve tavsiyelerini anlatan bu yazı umarım sizlere faydalı olur.
..."Son olarak Oracle Magazine tarafından bu yılın Oracle DBA’i (DBA of the year) seçilince, kariyerimde bir basamak daha arkamda kaldı. Bu yazıda benim dünya klasmanında bir Oracle veritabanı uzmanı olmamda işime yarayan ipuçlarını bulacaksınız. Bu yazıyı her ne kadar Oracle Veritabanı ekseninde yazsam da ipuçları bütün teknik uzmanlıklara sanırım uygulanabilir. Bu ipuçlarının genç uzman adaylarına yardımcı olması dileklerimle…
Âşık Olun
Benim için, Oracle kariyer yolu hiçbir zaman “karın doyurmak için bir araç” olmadı. Bugün yaptığım şey 12 yaşlarında QBASIC ile başladığım serüvenin sadece son halkasıdır. O zamanlardan beri bu işle yattım bu işle kalktım diyebilirim.Doğruyu söylemek gerekirse hiçbir zaman “Bu işin bana dönüşü ne olur, ne olmaz ?” diye düşünmedim. Sevdikçe uğraştım, uğraştıkça daha da sevdim.
Genelde “Oracle ile iyi para kazanabilmek için mi uğraşmalıyım ?” sorusuyla karşılaşıyorum. Dürüst olmak gerekirse “çok para” kazanmanın son tercih edilecek yollarından biri Oracle (onca bug, crash, vs. düşünülünce) galiba. Ben bunun yerine kendi sebebimi açıklamak adına “Oracle ile uğraşıyorum, çünkü büyük veritabanlarıyla uğraşmayı seviyorum” cümlesini tercih ediyorum.Bir ihtiyaç önüme geldiğinde; en ucuz(cost-effective), en sağlam (robust), en performanslı (scalable) yolu bulmaya çalışmak benim için hep bir mücadele:Çözümü araştırmak, bulmak, geliştirmek ve ondan sonra da keyifle çalıştığını izlemek…
Çırak Olun, Kalfa Olun, Usta Olun
Fikrimi sorarsanız kurumsal arenada iyi bir teknik oyuncu olmanın yolu usta-çırak modelinden geçiyor. Geriye dönüp baktığımda üniversite yıllarından beri benim en büyük şansım hep iyi ustaların karşıma çıkmış olması (Hasan Tonguc Yılmaz ve Yomi Kastro’ya teşekkürler). Bu ustalar teknik bilgiyi öğretmekten ziyade, bulunduğunuz coğrafyaya tıkılmak yerine dünya klasmanında oynamanız için gerekecek ve yaptığınız işte hep en iyi olmanızı sağlayacak ipuçlarını vereceklerdir.
Bir diğer önemli adım ise usta olmak. Bunun bir açıdan önemi vefa borcunuzu ödemek olarak değerlendirilebilir. Ama daha önemlisi sizin kendinizi ilerletmeniz ile alakalı olan kısımdır. Takdir edersiniz ki bir şeyi bilmek ile onu başkalarına anlatabilmek arasında çok fark var. Eğer birisine koçluk etmeye başlarsanız sunum yetenekleriniz gelişir, teknik detayları teknik olmayan insanlara (yöneticilerinize, müşterilerinize, vs) çok daha kolay indirgersiniz, kendi bilginizi sorular karşısında sınar, bilginizi sürekli taze tutmak ile alakalı önemli bir motivasyon kazanırsınız.
Bilgiyi Paylaşın
Ticaretle uğraşan bir ailenin ferdi olarak bize hep öğretilen meslek sırlarını hiçbir zaman paylaşmamaktı. Bilgi teknolojilerini kendime kariyer yolu olarak seçtikten sonra bu alanda başarılı ve tanınan biri olmanın en büyük yolunun bilgiyi saklamak değil, bilginin yayılmasını sağlamak olduğunu anladım. Bilginin bugün saklanması neredeyse imkânsız. Ya siz o bilgiyi yayar ve insanların ilgisini çekersiniz veya başkası o bilgiyi yayar ve siz sakladığınızla kalırsınız.
Sunum yapmak, blog yazmak, forumlara cevap vermek sizin bilinirliğiniz açısından çok ama çok önemlidir. Bu nokta da sakın ben daha stajyerim, yarı zamanlı çalışanım, çalışmaya yeni başladım endişelerine kapılmayın. Herkesin üzerine çalıştığı konuyla alakalı söyleyecek mutlaka bir çift lafı vardır.
Birlikte Çalıştığınız ve Fikir Danıştığınız Kişilerin Önemi
Özellikle kurumsal uygulamalar söz konusu olduğunda projelerde her zaman bir takım ekiplerle çalışıyoruz. Büyük projeler yaptığınızda veya bir şeyleri değiştirdiğiniz de ilerlemeniz de kaplumbağa gibi değil tavşan gibi sıçramalar şeklinde olacaktır. Ama hiçbir şey maliyetsiz gelmiyor. Bu tarz projelerde sorun yaşarsanız düşüşler de yüksekten olacaktır.Dolayısıyla yola çıktığınız veya akıl hocalığına başvurduğunuz kişiler sizi bitiş çizgisinde ayakta tutacak olan şeyin ta kendisidir. Benim için hep böyle oldu. Örneğin, veri ambarı konusunda Uğur Demirelçe ve Mustafa Altuğ Kamaci, Linux ve Oracle konularında Orhan Bıyıklıoğlu ve Ersin Ünkar yaptığımız büyük işlerde her zaman akıl hocalarım ve gözüm kapalı güvendiğim kimseler olmuştur.
Yeniyi Siz Getirin
Eskiye rağbet olsa bitpazarına nur yağardı. Yeniden sakın korkmayın. Oracle Magazine’de yayınlanan röportajımda sarf ettiğim cümlelerin en önemlilerinden biri kanımca suydu:
İyi teknik adam hep yeniyi kullanmaya karşı bir heyecan duymalı, ama kullandığı ürününün sınırlarını da çok iyi test edip bilmeli.
Geriye dönüp baktığımda yeni kavramı benim kariyerimde çok önemli bir yer tutuyor. Bazılarını sıralamak gerekirse:
Turkcell içerisinde
Turkcell’e Oracle Database Beta testing kavramını 11g Release 2 ile getirmek
Turkcell’in ilk büyük çaplı RAC projesini tasarlamak
Turkcell’i ASM ile tanıştırmak
Turkcell’in Oracle CAB’de temsil edilmesini sağlamak
Türkiye
Türkiye’nin ilk ve tek Oracle ACE Director’ü ve Yılın DBA olmak
Dünya
Dünyanın en genç Oracle Director’ü ve Yılın DBA olmak
Gördüğünüz üzere yeniliği ve ilki her seviyede gerçekleştirebilirsiniz. İlk bilmek, ilk denemek vs hep tutkunuz olsun.
Sorunla Karşılaştığınızda Ağınız Hazır Bulunsun
Şunu unutmayınız ki projelerin hiç biri sorunsuz gelmeyecektir. İllaki bir bug veya tasarım aşamasında bazı sorularınız, sorunlarınız olacak. Burada mühim olan sorun yaşadığınızda kaç kişi ile bu sorunun üzerine gidebildiğiniz. Benim tercihim her zaman mümkün olduğunca farklı ve fazla profile ile Oracle problemlerine saldırmaktır:
Kendi ekibinizdeki uzmanlar
Metalink Support kanalı
Oracle Development takımı
Oracle Proje Yönetim takımı
Uzmanlığına güvendiğiniz yerel veya yurtdışı uzmanlar
Uzmanlığına güvendiğiniz yurtdışı Oracle Support üyeleri
Liste bu kadar uzun olunca ilk akla gelebilecek soru, bu kadar kişiyi nasıl ayağa kaldırabiliriz olacaktır. Genelde problemlerle karşılaşan insanlar da gördüğüm sorun, problem yaşadıklarında herkesi hareket için davet etmek. Ama bunun pek de çalışan bir metot olduğunu söylemek zor.Burada izlenmesi gereken yol daha sorun ortada yokken ve hatta belki proje bile ortada yokken ağınızı kurmak ve onu harekete hazır hale getirmek. Bunu çeşitli toplantılarda, konferanslarda, ilgili kişilere mailler atıp yaptığınız işi ve kendinizi tanıtarak yapabilirsiniz. Sizi unutmalarına izin vermezseniz her daim harekete hazır bir destek ordunuz olur.
DBA mi Developer mi?
Hep kulağımıza gelen bir diğer soru “kariyer yolumu yazılım geliştirici mi yoksa DBA olarak mı şekillendirmeliyim” oluyor. Ben Turkcell’de staja ilk başladığımda Oracle yazılımcısı idim, daha sonra bir startupda yazılım ekibi yönettim, son olarak da Turkcell’e veri tabanı yöneticisi olarak geri döndüm.
Bunların hiç birisi tek başına sizi uzmanlık mertebesine taşıyacak şeyler değil sadece kartvizitinize yazılacak olan birer “Ünvan”dır. Oracle o kadar garip bir sistem ki maalesef ben developerim veya ben DBA’im diyenleri pek sevmiyor. “İyi” olmak istiyorsanız bir DBA kadar DBA, bir developer kadar developer ve hatta OS ve hardware konusunda da yeteri kadar bilgili olmalısınız. Çünkü bunların her hangi birinde çıkabilecek sorunun sonucu “failure” olarak geri dönecektir. Uzmanın görevi ise bunu önlemektir.
Temellere Önem Verin (Return to Basics)
Öğrencilik döneminde ve sonrasında hep sorulan sorulardan biri “Üniversitede öğrendiklerim ne işime yarayacak ?” oluyor. Kısaca çok işinize yarayacak diyebilirim. Biraz açmak gerekirse kuyruk teorisinden(Queuing Theory) örnek vereyim. Kuyruk teorisinin temellerini anlamamış bir kimsenin Oracle’da veya işletim sistemi seviyesinde göreceği herhangi bir bekleme olayını tam manası ile anlaması mümkün değildir. Defalarca şahit olduğun bir kargaşa servis zamanı ile bekleme zamanı metriklerinin bir birine karıştırılmasıdır.
Dolayısıyla bugünün bilgisayar yazılımları sadece dört işlemi yapabilen uzmanlar için fazla karmaşık. O yüzden olasılık teorisi, kuyruk teorisi, simulasyon sistemleri, vs gibi temel(core) mühendislik dersleri (veya derslerin hocaları) ne kadar sıkıcı olursa olsun kesinlikle bir uzman adayı tarafından iyi anlaşılmalı ve gerçek hayatta kullanabilecek kadar sindirilmeli. "
Add Months() Fonksiyonu
ADD_MONTHS Fonksiyonu ve Gün Ekleme
Merhaba arkadaşlar, Bu makalemde add_months() fonksiyonundaki bir takım incelikleri sizlerle paylaşacağım. Tarih bilgisi içeren önemli ve kritik raporlarınızda kesinlikle dikkatinizden kaçmaması gereken bir konu olduğunu düşünüyorum.
SQL tarih fonksiyonlarından biri de add_months fonksiyonudur. Bu fonksiyonun çeşitli kullanım şekilleri vardır. Fakat fonksiyonun temel mantığı; girilen bir tarihten itibaren, verilen ay sayısı kadar geriye veya ileriye gitmektir. Fonksiyonu analiz edersek ;
add_months(‘date’,number) şeklinde;
-date à girdiğimiz bir tarih,
-number à herhangi bir sayı (3,8,-4 gibi)
Şimdi fonksiyonu birkaç örnekle inceleyelim :
|
İfade |
Sonuç |
1 |
ADD_MONTHS('10-APR-2010', 2) |
10/06/2010 |
2 |
ADD_MONTHS(SYSDATE,2) |
07/02/2011 14:00:15 --(çalıştırdığım tarih üzere) |
3 |
ADD_MONTHS('15-JUL-1988',-2) |
15/05/1988 |
4 |
ADD_MONTHS('31-JAN-2010', 1) |
28/02/2010 |
5 |
ADD_MONTHS('30-JAN-2010', 1) |
28/02/2010 |
6 |
ADD_MONTHS('29-JAN-2010', 1) |
28/02/2010 |
7 |
ADD_MONTHS('28-JAN-2010', 1) |
28/02/2010 |
8 |
ADD_MONTHS('27-JAN-2010', 1) |
27/02/2010 |
9 |
ADD_MONTHS('30-JUN-1988',1) |
31/07/1988 |
10 |
TO_DATE('31-JAN-2010') + 30 |
02/03/2010 |
Yukarıdaki tablonun her satırındaki örnekleri dikkatle incelemekte fayda var.
Tablodaki örneklerden ilkinde ; 10 nisan 2010 tarihine , 2 ay ekliyoruz ve sonuç olarak 10 haziran tarihine gidiyoruz. Aynı şekilde 3. Örnekte 15 temmuzdan 2 ay geriye giderek 15 mayıs tarihine geliyoruz fakat dikkat etmemiz gereken önemli bir nokta var : O da 4 ve sonraki satırlardaki örnekler.
4. Örnekte, 31 ocak tarihine bir ay eklediğimizde 28 Şubata gidiyor. Yani bu fonksiyon mantık olarak seçilen tarih üzerine 30 gün eklemiyor. Takvim üzerinde direk belirtilen günden “x ay sonrasına” gidiyor. 4,5,6 ve 7. Satırlardaki ifadelerin aynı sonucu döndürmesinin sebebi budur. 30 ocaktan 1 ay sonra da 28 şubattır; 28 ocaktan 1 ay sonra da 28 şubattır. Burada dikkat edilmesi gereken, ay ekleme işlemini gün bazında değil takvim bazında yapmasıdır.
10. örneğe baktığımızda ise ekleme işlemi tamamen gün bazında yapılmaktadır. Yani verilen tarihin üstüne takvim üzerinden x sayıda gün eklenir ve o sonuç döndürülür.
Oracle index kullanımı
Veritabanina gönderdigimiz SQL sorgularina daha kisa sürede yanit almak ve daha düsük donanim gücü tüketmesi açisindan için çogu zaman veritabanina yeni indeksler ekleriz. Sunucuya gönderilen sorgunun içerigine göre olusturdugumuz bu indekslerin kullanim sikligina Oracle veritabani cost based hesabi yaparak (execution plan) karar vermektedir. Bu konuda veritabanindaki mevcut indesklerin hangi siklikla kullanilacagina spesifik olarak “optimizer_index_cost_adj” isimli Oracle sistem parametresi karar verir.
Optimizer_index_cost_adj parametresini biraz açarsak, “1? ile “10.000? arasinda bir deger atayarak (default deger 100) Oracle ‘in indeks hassasiyetini arttirip azaltabilirsiniz. Buna göre parametreye atanacak düsük bir degerde (10-50 arasinda) Oracle sonucunu almak istediginiz sorguya uygun olan bir indeks kullanmaya (force) çalisacaktir. Paremetreye verilecek olan deger arttirildigi taktirde (misal 200-10.000 arasinda) Oracle indeks kullanimindan feragat ederek tablo üzerinde full tablescan ‘e yönelecektir.
Performance tuning amaçli kullanilan optimizer_index_cost_adj parametresini kendi sisteminize uyarlarken dikkat edilmesi gereken nokta, parametrenin degeriyle oynamadan önce veritabanin güncel istatistiginin alinmasidir. Buna göre parametre degisikliginden kaynakli olusabilecek yanlis execution plan kullanimi ve akabinde yasanacak performans kaybinin önüne geçilebilir.
Asagida örnek bir sorgu çalistirarak konuyu açiklamaya çalisacagim.
* Öncelikle optimizer_index_cost_adj parametresinin degerini “10? olarak degistiriyorum.
SQL> alter system set optimizer_index_cost_adj=10 scope=memory;
* SQL sorgunun execution planini incelemek amaciyla trace ‘i etkilestirip sorgumu çalistiriyorum.
SQL> select count(*) from test.test_tbl where isim=ahmet, uyelik_tarihi>sysdate-100
--------------------------------------------------------------------------------
Plan name: SYS_SQL_PLAN_9ch1da8da5d612n3
Enabled: YES Fixed: NO Accepted: NO Origin: AUTO-CAPTURE
--------------------------------------------------------------------------------
Plan hash value: 7123371084
----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 32 | 22 (0)| 00:00:01 | | |
| 1 | SORT AGGREGATE | | 1 | 32 | | | | |
| 2 | CONCATENATION | | | | | | | |
| 3 | PARTITION RANGE ITERATOR | | 3 | 96 | 7 (0)| 00:00:01 | KEY | KEY |
|* 4 | TABLE ACCESS BY LOCAL INDEX ROWID| TEST_TBL | 3 | 96 | 7 (0)| 00:00:01 | KEY | KEY |
|* 5 | INDEX RANGE SCAN | TEST_TBL_IDX1 | 2 | | 7 (0)| 00:00:01 | KEY | KEY |
| 6 | PARTITION RANGE ITERATOR | | 90156 | 2817K| 7 (0)| 00:00:01 | KEY | KEY |
|* 7 | TABLE ACCESS BY LOCAL INDEX ROWID| TEST_TBL | 90156 | 2817K| 7 (0)| 00:00:01 | KEY | KEY |
|* 8 | INDEX RANGE SCAN | TEST_TBL_IDX1 | 2 | | 7 (0)| 00:00:01 | KEY | KEY |
| 9 | PARTITION RANGE ITERATOR | | 8 | 256 | 7 (0)| 00:00:01 | KEY | KEY |
|* 10 | TABLE ACCESS BY LOCAL INDEX ROWID| TEST_TBL | 8 | 256 | 7 (0)| 00:00:01 | KEY | KEY |
|* 11 | INDEX RANGE SCAN | TEST_TBL_IDX1 | 2 | | 7 (0)| 00:00:01 | KEY | KEY |
----------------------------------------------------------------------------------------------------------------------
* Oracle ‘i mevcut indeksleri daha fazla kullanmasi için düzenledikten sonra, yukaridaki detayli execution plan dökümünden anlasilacagi üzere çalistirdigimiz sorgu tabloda dogru indeksi tespit edip (veritabani istatistiginin güncel olmasina bagli olarak) kullandi.
* Simdi farkli bir deneme yapmak için optimizer_index_cost_adj parametresinin degerini “2000? olarak degistiriyorum. Bu noktada beklentim Oracle ‘in indeks kullanimindan uzaklasarak ayni sorgu için farkli bir execution plan seçmesi.
SQL> alter system set optimizer_index_cost_adj=2000 scope=memory;
* SQL sorgunun execution planini incelemek amaciyla yine trace islemini etkilestirip sorgumu çalistiriyorum.
SQL> select count(*) from test.test_tbl where isim=ahmet, uyelik_tarihi>sysdate-100
--------------------------------------------------------------------------------
Plan name: SYS_SQL_PLAN_1e5dda4d8748d58e
Enabled: YES Fixed: NO Accepted: YES Origin: AUTO-CAPTURE
--------------------------------------------------------------------------------
Plan hash value: 2481613860
-------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 32 | 1519K (1)| 05:03:50 | | |
| 1 | SORT AGGREGATE | | 1 | 32 | | | | |
| 2 | CONCATENATION | | | | | | | |
| 3 | PARTITION RANGE ITERATOR| | 3 | 96 | 506K (1)| 01:41:16 | KEY | KEY |
|* 4 | TABLE ACCESS FULL | TEST_TBL | 3 | 96 | 506K (1)| 01:41:16 | KEY | KEY |
| 5 | PARTITION RANGE ITERATOR| | 90156 | 2817K| 506K (1)| 01:41:17 | KEY | KEY |
|* 6 | TABLE ACCESS FULL | TEST_TBL | 90156 | 2817K| 506K (1)| 01:41:17 | KEY | KEY |
| 7 | PARTITION RANGE ITERATOR| | 8 | 256 | 506K (1)| 01:41:17 | KEY | KEY |
|* 8 | TABLE ACCESS FULL | TEST_TBL | 8 | 256 | 506K (1)| 01:41:17 | KEY | KEY |
-------------------------------------------------------------------------------------------------------
* Yukaridaki tablodan da anlasilacagi üzere çalistirdigimiz sorgu tabloda full tablescan ‘e girdi. Her ne kadar kullanmakta oldugum tablo partitioning yapilmis olsada sorgu indeks kullanmadigi için daha yüksek bir cost ‘a sahip. Yanliz bu cümleden her zaman indeks kullanmak performans kazandirir gibi bir düsünce olusmamali çünkü, indeks kullanim performansi mevcut tablonuza ve bu tabloya gönderdiginiz SQL sorgusunun içerige bagli olarak degisiklik gösterebilir.
Konuyu sonuca baglamak gerekirse, optimizer_index_cost_adj parametresi Oracle ‘in veritabani performansini dogrudan etkileyebilecek sistem parametrelerinden bir tanesi. Farkli uzmanlar bu parametre için farkli degerler kullanilmasini öneriyor. Örnek olarak ünlü Oracle uzmani Tom Kyte bu parametrenin AWR raporlari gözlenerek cache/hit oranina göre ayarlanmasi gerektigini belirtiyor. Digerleri OLTP sistemler için optimizer_index_cost_adj parametresinin “10-50? arasinda ayarlanmasinin performansa büyük etkisi olacagi görüsünü paylasiyor. Sonuç itibariyle veritabanin performansina dogrudan etki edecek bir parametre için bende öncelikle AWR raporlarini takip edilmesi konusunda hem fikirim.
boraovali.com
PL-SQL (ORACLE) Fonksiyonları / Decode, NVL, NVL2
PL-SQL Fonksiyonlari : NVL
NVL(deger, deger_Null_ise_bu_deger_ile_degistir )
fonksiyonu eger deger ifadesinin degeri "null" ise, deger_Null_ise_bu_deger_ile_degistir ifadesi ile degistirir. Diger durumlarda deger i geri döndürecektir.
Fonksiyonun amaci, null olarak gelen degerleri, belirtilen deger ile degistirmektir. Bu islev ile ilgili alandaki tüm degerlerin "null" olmamasi garanti edilir.
Nerelerde tercih edilir ?
- Çogunlukla sayisal bir deger döndürmesi beklenen alanlardaki veriler eger "null" ise 0 ile degistirmek için kullanilir. Örnegin, müsterilerin yil yil gerçeklestirdigi tüm ödemeleri toplamak istiyorsunuz. Her bir müsterinin her yil için ödeme yapmamis olacagi olasi ve beklendik bir durumdur. Dolayisiyla müsteri ile dönem ve ödeme tablosunu "left join" ile bagladiginizda, bazi dönemlere ait ödeme kayitlariniz "null" olarak gelecektir. Aritmetik isleme dahil edebilmek için bu alanlari 0 ile degistirmeniz gerekmektedir.
- String degerleri birlestimek istediginizde, "null" kontrolu yapmaniz gerekmektedir. Çünkü birlestireceginiz alanlar (metinler) içinde eger bir tane bile "null" degere sahip alan varsa, tüm ifadeniz "null" olacaktir. Bu durumda "null" olan degeri '' (bos karakter) ile degistirmeniz gerekmektedir. Örnegin, il , ilçe ve semt taniminin bulundugu tablonuzdaki bu alanlari birlestirerek müsterinin adresini tek satir halinde elde etmek istiyorsaniz, bu alanlardan herhangi birisinin girilmemis olma ihtimalini (null olma ihtimali) göz ardi etmemelisiniz aksi taktirde sadece semt bilgisi girilmemis kayitlar için bile tüm adres degerini "null" olarak elde edersiniz.
select NVL(donem_toplami,0) as toplam ...
select NVL(metin1,'') || NVL(metin2,'') || ... || NVL(metinN,'') as olusturulanMetin ...
PL-SQL Fonksiyonlari : NVL2
NVL2( deger, deger_Null_degilse_bu_deger_ile_degistir, deger_Null_ise_bu_deger_ile_degistir)
fonksiyonu deger i eger deger NULL degilse 2. parametre ile NULL is 3.parametre ile degistirir.
Özellestirilmis bir IF-ELSE yazimidir. Eger alan "null" degil ise deger_Null_degilse_bu_deger_ile_degistir degeri ile , "null" ise deger_Null_ise_bu_deger_ile_degistir degeri ile degistirir.
Nerede tercih edilir ?
- Bir alanin "null" olup olmama durumuna göre kullaniciya anlamli bir mesaj vermek istediginizde kullanabilirsiniz. "null" ise YOK , degil ise VAR yazmak için kullanabilirsiniz.
PL-SQL Fonksiyonlari : DECODE
Decode( ifade, aranan_deger1, aranan_deger1e_esit_ise_bu_deger_ile_degistir,aranan_deger2 ,aranan_deger2e_esit_ise_bu_deger_ile_degistir, [aranan_degerN, aranan_degerNe_esit_ise_bu_deger_ile_degistir]... [hicbiri_ile_eslesmedi_ise_bu_deger_ile_degistir] )
fonksiyonu ifade içersinde aranan_deger1 ... aranan_degerN degerlerini arar ve ifade hangi aranan_deger e karsilik geliyor ise aranan_degere_esit_ise_bu_deger_ile_degistir degerini döndürür.
Fonksiyonu IF-THEN-ELSE-END kullanimina karsilik gelir. Pl-Sql özelinde CASE-WHEN-ELSE-ENDCASE-WHEN kalibinda istediginiz herhangi bir kosulu kullanabilirken, Decode esitlik durumlari için elverislidir. kalibina karsilik gelir. Bu kalibin esitlik durumlari için özellestirilmis halidir. Yani
Nerelerde tercih edilir ?
- NVL fonksiyonlari sadece "null" ile kiyaslama yaparken, Decode fonksiyonu herhangi bir deger ileNVL fonksiyonlarini kapsar. Onlarin kullanildigi heryerde kullanilabilir. kiyasma yapabilme imkani tanir. Dolayisyla
- Belirli kodlara karsilik, bazi tanimlar yazilmak isteniyorsa kullanilir. Örnegin, Decode(IL_KODU,34, 'ISTANBUL', 10, 'BALIKESIR' , 10.5 , 'BANDIRMA' , 35, 'IZMIR' , 35.5 , 'KARSIYAKA', 'TÜRKIYE') de oldugu gibi dönen il koduna göre ISTANBUL,BALIKESIR, BANDIRMA ... yada hiç eslesen olmamasi durumda TÜRKIYE döndürmek için kullanilabilir.
- Referans tablolari olmayan degerleri anlamlandirmak için kullanilabilir. DECODE(Alan,1,'Evet', 0, 'Hayir','Belki') seklinde tanimlarsak, Alan'dan dönen deger 1 ise Evet , 0 ise Hayir , 1 veya 0 dan farkli bir deger döner ise Belki degerini geri döndürecektir.
Alintidir --> http://dervisali.blogspot.com/2008/06/oracle-functions.html
Temporary Tablespace Alanı Hakkında
Oracle veritabaninda büyük ölçekteki sort islemleri için sunucumuzun hafizasi (RAM) yetersiz kaldiginda, bu islemlerin sabit disk üzerinde gerçeklestirilmesi gerekmektedir. Bu islemlerin sabit disk üzerinde gerçeklestirildigi Oracle veritabani alanina temporary tablespace denilir. Temporary tablespace ‘in diger tablespace ‘lerden farki, mantiksal anlamda datafile degil tempfile kullanmasidir. O nedenle temporary tablespace ‘e yeni bir datafile eklenecegi zaman komut içersinde datafile degil, “tempfile” ifadesini kullaniriz.
Veritabanimizin temporary tablespace alanini resize edemedigimiz durumlarda veya yeni bir temporary tablespace alanina ihtiyacimiz duydugumuzda asagidaki yönergeleri takip ederek yeni bir temporary tablespace alani olusturabiliriz. Bu konuda dikkat etmemiz gereken husus, default temporary tablespace alani kullanicilar tarafindan aktif olarak sort v.b islemler kullanildigindan, eski temporary tablespace alanini drop etmeden önce yeni temporary tablespace ‘in olusturulmasinin gerekliligidir. Simdi sirasiyla yeni temporary tablespace alanini olusturup, eksisini sistemden kaldiralim.
- Öncelikle kendimize yeni bir temporary tablespace alani olusturulalim. Tablespace içersindeki datafile ‘in büyüklügünü ihtiyaciniza göre ayarlayabilirsiniz. Olusturacagimiz yeni tablespace alani için asagida 16Gb ‘lik bir datafile ekledim fakat, büyük ölçekte kayitlara sahip tablolar tutuyorsaniz buna göre daha genis temporay tablespace kullanmaniz gerekebilir.
SQL> create temporary tablespace YENITEMP tempfile '/oracle/data/yenitemp1.dbf' size 16384M autoextend on next 512M maxsize 32767M;
- Yeni temporary tablespace alanini veritabanina ekledik. Simdi yeni ekledigimiz temporary tablespace alanini, default tablespace olarak atayalim. Bundan sonra yapilacak olan sort islemleri artik yeni olusturdugumuz tablespace ‘de gerçeklestirilecek.
- Yeni default temporary tablespace alanimizi kullanmaya basladik, artik eski temporary tablespace alanini drop etmeye haziriz.
SQL> alter database default temporary tablespace YENITEMP;
SQL> drop tablespace ESKITEMP including contents and datafiles;
Tebrikler.
boraovali.com
Table Partition oluşturma
Gittikçe büyüyen ve data yükü artan tablolar üzerinde sorgu çalıştırmak veya tablo bakımına ait diğer işlemleri gerçekleştirmek zamanla çeşitli problemlere sebep olmaktadır. Problemleri ortadan kaldırmanın kullanışlı ve etkili yollarından birisi tabloyu bütünlüğünü koruyacak şekilde parçalara ayırmak ve ilgili işlemleri sadece gerekli olan parçalar üzerinde yapmaktır. Partitioning kavramı bahsedilen bu işlemleri gerçekleştirebileceğimiz bir yapı sunmaktadır, tablonun bütünlüğü korunarak üzerindeki işlemlerin daha hızlı gerçekleştirilebileceği parçalara ayrılır.
Partitioning kavramı üzerinde bahsedilmesi gereken ayrıntılarla devam etmek istiyorum, tablo üzerinde partition oluşturmak tablonun genel bütünlüğünü bozmayacağından tablo üzerinde çalıştırılan sorgularda değişiklik yapmaya gerek yoktur. Bu nedenle işleyen sistemler üzerinde uygun partition metodunu seçerek kullanılan sorguları değiştirmeden partitioning işlemi gerçekleştirilebilir. Aynı zamanda partitioning metoduna bağlı olarak ayrılan her parçanın kendi ismi ile sadece ayrılan parçaya ait işlemler de gerçekleştirilebilir. Parçalar ayrı ayrı drop/truncate edilebilir, üzerlerinde farklı bir index oluşturulabilir. Partitioning in diğer avantajı ise küçük parçalar ile uğraştığından sorgularda çok daha performanslı olmasıdır. Ayrıca partitioning yapılmamış bir tabloya sonradan partitioning yapıldığında tablo üzerinde çalışan sorgu ve DML lerde herhangi bir değişikliğe gerek olmaması bu yapının oldukça esnek olarak kullanılmasını sağlamaktadır.
Partition lara ayrılan bir tabloda herbir satır tek bir parçaya ait olabilir, satırın ait olacağı parçanın belirlenmesi için partition key kullanılır. Partition key null alabilen bir değerden de oluşabilir.
Yukarda bahsettiğim gibi bazı işlemlerin gerçeklenebilmesi tablo üzerindeki partitioning metoduna bağlıdır. Partitioning metodlarını daha yakından inceleyecek olursak:
Oracle tarafından 4 farklı partitioning yöntemi desteklenmektedir:
· Range Partitioning.
· List Partititoning
· Hash Partitioning
· Composite Partitioning
Range Partitioning Metodu
Range metodu ile partition işleminde partition keyi üzerinde belirli aralıklardaki değerlere göre parçalar oluşturulur. Örneğin tablo üzerinde yılların tutulduğu bir alana sahibiz, bu alanı partition key olarak belirleyip yıllara göre parçalar oluşturabilir, artık kullanmayacağımız yılların datalarını direk ilgili partitionu kullanarak drop/truncate edebilir veya belirli bir yıla göre sorgularımızı gerçekleştirebiliriz. Veya illere göre verilerin tutulduğu bir tabloda il kolonu üzerinde partition yapılarak sadece ilgilenilen ilin datası ile işlemler yapılabilir. Partitionda less than ile belirtilen değerden daha küçük olan aralık alınır, MAXVALUE değeri ile ise bir üst sınır belirlenir, belirlenen en büyük değerin dışına çıkan ve null olan değerler bu parça içerisine dahil olacaklardır.
Number tipe gore range partition örneği:
CREATE TABLE emp (
empno NUMBER(4),
ename VARCHAR2(30),
sal NUMBER
)
PARTITION BY RANGE(empno) (
partition e1 values less than (1000) tablespace ts1,
partition e2 values less than (2000) tablespace ts2,
partition e3 values less than (MAXVALUE) tablespace ts3
);
Emp tablosu üzerinde empno keyi kullanılarak bir partition oluşturulmuştur ve 1000 den küçük olan numaralar, 1000-2000 arası olan numaralar ve 2000 den büyük olan numaralar ayrı partitionlarda yer alacaklardır.
Varchar2 string tipe gore partition örneği:
CREATE TABLE emp
( id NUMBER(5) PRIMARY KEY,
name VARCHAR2(50) NOT NULL,
phone VARCHAR2(15),
email VARCHAR2(100) )
PARTITION BY RANGE ( name )
(
PARTITION p1 VALUES LESS THAN ('L') TABLESPACE ts1,
PARTITION p2 VALUES LESS THAN (MAXVALUE) TABLESPACE ts2
)
Date tipe gore range partitioning örneği:
CREATE TABLE t1 (id NUMBER, c1 DATE)
PARTITION BY RANGE (c1)
(PARTITION t1p1 VALUES LESS THAN (TO_DATE('2007-11-01', 'YYYY-MM-DD')),
PARTITION t1p2 VALUES LESS THAN (TO_DATE('2007-12-01', 'YYYY-MM-DD')),
PARTITION t1p3 VALUES LESS THAN (TO_DATE('2008-01-01', 'YYYY-MM-DD')),
PARTITION t1p4 VALUES LESS THAN (MAXVALUE)
);
Hash Partitioning Metodu
Hash partitioning metodu daha çok key olarak range metodundaki gibi bir sınır belirlenemeyecek olan alanlar üzerinde kullanılır, örneğin kimlik numaralarının tutulduğu bir alan üzerinde oluşturulabilir.
Örnekler:
create table emp2 (
empno number(4),
ename varchar2(30),
sal number
)
partition by hash(empno) (
partition e1 tablespace emp1,
partition e2 tablespace emp2,
partition e3 tablespace emp3,
partition e4 tablespace emp4
);
Emp2 tablosu üzerinde farklı tablespaceler kullanılıp empno alanı key olarak kullanılmış ve partition oluşturulmuştur.
create table emp2 (
empno number(4),
ename varchar2(30),
sal number
)
PARTITION BY HASH(empno)
PARTITIONS 3
STORE IN (empts1, empts2, empts3);
Hash Partitioning yönteminde partitionlar round robin mantığı ile oluşturulurlar.
List partitioning
List partitioning methodu ile belirlenen bir liste değerini içerek key üzerinden tablo partitionlara ayrılır.
Örnek:
emp# NUMBER PRIMARY KEY,
ename VARCHAR2(30),
salary NUMBER(8,2),
deptno NUMBER)
PARTITION BY LIST (deptno) ( -- Add list partitioning
PARTITION p10 VALUES (10),
PARTITION p20 VALUES (20),
PARTITION p30 VALUES (30,40));
deptno alanı key olarak kullanılmış ve bu alan için belirlenen değerler için tablo içerisinde parçalar oluşturulmuştur.
List partition için ayrıca listede belirtilmeyen veya listede yer almayıp sonradan eklenebilecek olan değerler ve null değerler için DEFAULT VALUE kullanılır.
CREATE TABLE myemp_work (
emp# NUMBER PRIMARY KEY,
ename VARCHAR2(30),
salary NUMBER(8,2),
deptno NUMBER)
PARTITION BY LIST (deptno) ( -- Add list partitioning
PARTITION p10 VALUES (10),
PARTITION p20 VALUES (20),
PARTITION p30 VALUES (30,40)
PARTITION PDEF VALUES(DEFAULT));
Composite Partitioning
Composite partitioning yöntemi diğer kullanılan yöntemlerin beraber kullanılması ile elde edilen bir yöntemdir. Daha önceden üzerinde partitioning oluşturulmuş olan bir tablodaki parçalar üzerindeki alt parçalar da parçalara ayrılarak verinin içeriğine ve kullanım amacına göre daha kullanışlı bir yapı sağlanabilir.
Range-hash ve range-list metodları birlikte kullanılarak yerine göre avantajlı olan özelliklerinden faydalanılabilir.
Örnek range-hash partitioning yapısı oluşturma:
CREATE TABLE orders(
ord# NUMBER,
orderdate DATE,
prod# NUMBER,
quantity NUMBER)
PARTITION BY RANGE(orderdate)
SUBPARTITION BY HASH(prod#) SUBPARTITIONS 4 -- STORE IN(ts1, ts2, ts3, ts4)
( PARTITION q1 VALUES LESS THAN (TO_DATE('01-APR-2009', 'DD-MON-YYYY')),
PARTITION q2 VALUES LESS THAN (TO_DATE('01-JUL-2009', 'DD-MON-YYYY')),
PARTITION q3 VALUES LESS THAN (TO_DATE('01-OCT-2009', 'DD-MON-YYYY')),
PARTITION q4 VALUES LESS THAN (MAXVALUE)
);
Bahsedilen partitioning methodlarından en uygun olanını seçmek verinin tipine, sunuluş şekline göre değişiklik gösterecektir, bu aşamada hepsinin avantajlı olan kısımlarını göz önünde bulundurarak seçim yapmak gerektiğini göz önünde bulundurmalıyız.
Partition işlemleri yaptığımız tablo üzerinde partitionlara ayrılmış kısımlar hakkında detylı bilgilere aşağıdaki sorguyu kullanarak bakabiliriz.
SELECT * FROM dba_tab_partitions WHERE table_name = '';
Dinamik SQL - 1
Arkadaslar bu makalemde sizlere dinamik SQL konusundan söz edecegim.
Dinamik SQL Nedir ?
Dinamik SQL, senaryosu çalisma zamanindan once bilinmeyen SQL cümlecikleri ile program yazma imkani saglayan bir tekniktir. Dinamik SQL’in detaylarina girmeden önce sizlere statik SQL den bahsetmek istiyorum. Böylelikle ikisi arasindaki farki daha net anlayacaginizi düsünüyorum. Statik SQL komutlari çalismadan çalismaya degismez. Komutun tüm senaryosu derlendigi anda bilinir ve herhangi bir alter islemi söz konusu olmadikça öylece sabitlenir ve su avantajlari saglar :
1) Hatasiz derlenmis bir SQL komutunda tüm objelerin veritabaninda geçerli oldugu bilinir,
2) Hatasiz derlenmis bir SQL komutunda tüm yetkilendirmelerin yerli yerinde oldugu bilinir.
3) Statik SQL komutlarinin sagladigi performans dinamik SQL’e göre daha üstündür.
Bu avantajlara baktigimizda dinamik SQL’I ancak, static SQL komutlariyla basaramadigimiz islerde veya static SQL komutlarinin kullanissiz kaldigi durumlarda kullanmayi tercih etmeliyiz.Her ne kadar statik SQL in kisitlamalari olsa da performans bakimindan dinamik SQL e nazaran üstündür. Içinizdeki soruyu duyar gibiyim, “e pekala neden dinamik SQL ?”…
Neden Dinamik SQL ?
Programlarinizda bazi anlarda yazacaginiz SQL komutlarinin full içerigini bilmeyebilirsiniz. Yani SQL sorgunuz, kullanicidan gelecek degisik input degerlerine gore sekillenme ihtiyaci duyabilir. Lafi karistirmadan hemen bir örnek verelim;
Bir datawarehouse ortaminiz var ve siz bu ortamdaki bir raporlama modülünüzdeki tablo isimlerini derlendigi tarihe gore atamak istiyorsunuz. Mesela INV_01_1997, INV_04_1997, INV_07_1997, INV_10_1997 gibi. Böyle durumlarda raporlama modülünüzde dinamik SQL kullanarak tablolarinizi çalisma zamaninda ‘create’ edebilirsiniz.
Veya programinizda bir listeleme modülü var ve siralamayi kullanicinin belirlemesini istiyorsunuz. Böyle bir durumda ‘order by’ fonksiyonu degisken olacaktir. Yani kullanici hangi kritere gore siralama yapmak istiyorsa ‘order by’ o kritere gore sekillenecektir. Böyle bir durumda da dinamik SQL kullanabilirsiniz.
PL/SQL Bloklari Içinde DDL ve SCL Kullanimi
PL/SQL içinde su tipleri static SQL’ e tercihen kullanabiliriz :
- DDL(Data Definition Language) cümleleri. ‘Create’, ‘Drop’, ‘Grant’, ‘Revoke’ gibi…
- SCL(Session Control Language) cümleleri. ‘Alter Session’, ‘Set Role’ gibi..
Bir örnek verecek olursak :
CREATE TYPE t_emp AS OBJECT (id NUMBER, name VARCHAR2(20))
/
CREATE TYPE t_emplist AS TABLE OF t_emp
/
CREATE TABLE dept_new (id NUMBER, emps t_emplist)
NESTED TABLE emps STORE AS emp_table;
INSERT INTO dept_new VALUES (
10,
t_emplist(
t_emp(1, 'SCOTT'),
t_emp(2, 'BRUCE')));
DECLARE
deptid NUMBER;
ename VARCHAR2(20);
BEGIN
EXECUTE IMMEDIATE 'SELECT d.id, e.name
FROM dept_new d, TABLE(d.emps) e -- not allowed in static SQL
-- in PL/SQL
WHERE e.id = 1'
INTO deptid, ename;
END;
Dinamik SQL Kullanim Alanlari
- Kullaniciya çalisma zamaninda sorgu seçimi veya kritere gore siralama v.s islem seçenegi sunan uygulamalar,
- Çalisma aninda veri girisi veya optimizasyon seçenegi sunan uygulamalar,
- Veritabanindaki tablo tanimlamalarinin (DDL statements) sürekli degisken oldugu uygulamalar,
- Istege ve ihtiyaca gore çalisma aninda create edilen tablo vb. objeler içeren uygulamalar.
Konunun basinda vermis oldugumuz datawarehouse örnegine bakarsak, tablo tanimini normalde biliyoruz fakat ismini çalisma aninda vermek istiyoruz. Dinamik SQL bu problemi çözüyor.
CREATE OR REPLACE PROCEDURE query_invoice(
month VARCHAR2,
year VARCHAR2) IS
TYPE cur_typ IS REF CURSOR;
c cur_typ;
query_str VARCHAR2(200);
inv_num NUMBER;
inv_cust VARCHAR2(20);
inv_amt NUMBER;
BEGIN
query_str := 'SELECT num, cust, amt FROM inv_' || month ||'_'|| year
|| ' WHERE invnum = :id';
OPEN c FOR query_str USING inv_num;
LOOP
FETCH c INTO inv_num, inv_cust, inv_amt;
EXIT WHEN c%NOTFOUND;
-- process row here
END LOOP;
CLOSE c;
END;
/
Datafile ve Tablespace Kavramları
DATAFILE VE TABLESPACE KAVRAMLARI
Oracle Veritabani üzerinde datalarin yani verilerin saklandigi yer fiziksel olarak DataFile mantiksal olarak ise TableSpace olarak ifade edilmektedir.
Bir veritabaninda verilerin nasil saklandiginin hiyerarsik yapisi asagidaki sekildeki gibidir :
Tablespace
Tablespace ler üzerinde ki islemler Tablespace online iken yapilmaktadir.
System Table space kesinlikle undo yada temp tablespace olarak kullanilmamalidir,
Tablespaceler read only yada normal mod arasinda çevrim yapilabilirler.
Not : Tablespace bir veya fazla datafile içierebilir fakat bir datafile ancak bir tablespace’e tahsis edilir.
DataFile
Bir DataFile yalnizca bir tablespace e verilebilir.
Büyüklügü ve optimizasyonu degistirilebilir
Segment
Bir Datafile bir yada birden fazla segment içerebilir,
Bir segment birden fazla Tablespace e dagilabilir
Extends
Bir Segment bir veya daha fazla extend ten olusur,
Bir segment yaratildiginda tek extend vardir ama daha sonra arttirilabilir,
DataBlocks
Extandler içinde bulunan en küçük birimdir,
Boyutu DB_BLOCK_SIZE ile Database yaratilirken belirlenir ve daha sonra degistirilemez.
Database bloklarinin büyüklügü isletim sistemi ile dogru orantilidir,
Oracle’ da bloklarin baslangiç boyutu DB_BLOCK_SIZE ile belirlenir. Bunun yanisira Oracle, standart olmayan bes farkli blok boyutu tanimlama olanagi sunar. Gereksiz I/O islemlerine engel olmak için veri blok uzunligu max sinirlar içinde isletim sisteminin blok uzunlugunun bir kaç kati olmalidir. Data bloklar, Oracle veritabaninin en küçük depolama birimidir.
Oracle Alert ve Trace Dosyaları
Bu makalemde kariyer hedefi olarak dba olmayi seçen arkadaslara yönelik bir konu paylastim. Dba konularina girdiginizde birçok gez alert ve trace dosyalariyla birebir iletisim halinde olacaksiniz :) çünkü bu dosyalarda veritabani ile ilgili önemli log'lar barindirilir ve dba pozisyonunda olan kisiler bu loglar araciligiyla veritabani sagliginda önemli roller oynayacaklardir.
ALERT VE TRACE DOSYALARI
Veritabani açilip kapatilirken veya bu asamanin adimlarinda herhangi bir hata durumunda olusan hatanin bilgileri alertSID.log dosyasina yazilir. Bu dosyada veritabani ile ilgili bütün bilgiler vardir. Dosyanin default yeri :
$ORACLE_HOME/rdbms/log
Lokasyonu BACKGROUND_DUMP_DEST parametresi ile belirlenebilir.
BACKGROUND TRACE
Background prosesler yürütülürken olusan hatalar sonucunda olusan dosyalardir. Lokasyonu BACKGROUND_DUMP_DEST parametresi ile belirlenir ve dosyanin formati SID_ProcessName_PID.trc seklindedir. Örnek olarak : db01_lgwr_23845.trc
USER TRACE
User prosessler üzerinde meydana gelen hatalar sonucunda olusan dosyalardir. Bu dosyalarin lokasyonu USER_DUMP_DEST parametresi ile belirlenir ve formati da SID_ora_PID.trc seklindedir. Örnek olarak : db01_ora_23845.trc bir user trace dosyasidir.
User Trace islemi yine bizde parametrelerce belirlenip yürütülebilen bir bilgidir.
Session bazli olarak,
SQL > ALTER SESSION SET SQL_TRACE = TRUE
Komutuyla,
Yada Paramatre file’indan
SQL_TRACE = TRUE yapilarak user trace enable edilebilir.
Adım Adım Oracle BI
ORACLE BI ANSWERS
Başlat -> Programlar -> Oracle Buisness Intelligence ->Welcome to Oracle BI EE tıklıyoruz.
Şekil-22
Oracle BI Interactive Dashboards linkine tıklıyoruz. Açılan sayfada “Answers” linkine bastığımızda browserda aşağıdaki (Şekil-23) deki ekran kesitini görebiliriz :
Şekil-23
Görüldüğü gibi Oracle BI Administrator arayüzünde presentation katmanındaki ARACTAKIP veritabanı burada görünüyor. Linke tıklayarak devam edelim.
Şekil-24
Yukarıdaki (Şekil-24) te görüldüğü gibi Presentation katmanında yaptığımız herşeyi burada görebiliyoruz. Ekranda görünen “Columns” bölgesine hangi alanları rapora dahil etmek istiyorsak onları koyuyoruz. “Filters” kısmında ise bunların nasıl görüneceğini belirteceğiz.
3.3.1 Columns
Ekranda görünen ARACTAKIP altındaki tablolara bağlı alanlardan hangilerini raporda görmek istiyorsak onlara tıklayarak sağdaki Columns kısmına dahil ediyoruz.
Şekil-25