pl/sql de object kullanımı
Merhaba
Daha önce size pl/sql type kullanımı örnek yazımda object kullanımı ile hazırladığımız bir type ile yazdığımız fonksiyonun table cast işlemi ile bir tablo gibi değerler döndürmesini anlatmıştım. Şimdi ise yine object kullanımı ile bir fonksiyon hazırlayacağız ama bu sefer table cast işlemi olmadan direk istediğimiz alana erişim ve birden fazla sütun olarak fonksiyon sonucumuzu alacağız. Bu örnek için fonksiyon içine göndereceğimiz tarih değerini bize sayısal, karakter ve tarih olarak geri dönecek bir bir yapı için bir object hazırlayalım ve fonksiyonumuzu yazalım.
create or replace type ExampleObject as object ( vNumber number, vVarchar varchar2(100), vDate date )
Artık object hazır. Şimdi bu object ile kullanacak olduğumuz fonksiyonumuzu hazırlayalım.
create or replace function ObjectFunction(vDate in date) return ExampleObject is vSayi number; vKarakter varchar2(100); vTarih date; vObject ExampleObject; begin vSayi := to_number(to_char(vDate, 'ddmmyyyy')); vKarakter := to_char(vDate, 'MONTH', 'nls_date_language=Turkish'); vTarih := vDate; vObject := ExampleObject(vSayi, vKarakter, vTarih); return vObject; exception when others then dbms_output.put_line('Hata:' || sqlerrm); end ObjectFunction;
Görüldüğü gibi fonksiyonumuzda hazır. Fonksiyon içindeki “vObject := ExampleObject(vSayi, vKarakter, vTarih);” satırı ile elimizdeki değişkenlerimizi object tipinin içindeki ilgili alanlara atamasını yapıyoruz. Şimdi hazır olan fonksiyonumuzu çalıştıralım ve sonuçlarına bakalım.
select ObjectFunction(sysdate) from dual;
Yukarıdaki kod çalıştığında bir tanımladığımız object içindeki tüm değişkenleri verecektir. Tablo düzgün çıkması için alan adlarındaki fonksiyon adını görselde kaldırdım sadece object isimlerini bıraktım.
VNUMBER | VVARCHAR | VDATE |
---|---|---|
1122013 | ARALIK | 01.12.2013 17:08:57 |
Bu özellik dışında ilgili fonksiyonun sonuna istediğimiz object elemanının adını yazarak da ilgili alanın değerini alabiliriz.
select ObjectFunction(sysdate).vNumber from dual;
OBJECTFUNCTION(SYSDATE).VNUMBE |
---|
1122013 |
select ObjectFunction(sysdate).vVarchar from dual;
OBJECTFUNCTION(SYSDATE).VVARCH |
---|
ARALIK |
select ObjectFunction(sysdate).vDate from dual;
OBJECTFUNCTION(SYSDATE).VDATE |
---|
01.12.2013 17:12:16 |
Bu örnektenda anlaşılacağı gibi ihtiyacınız olan bir durumda doğru bir şekilde hazırlanan object ve fonskiyon yapısı ile bir seferde birden fazla içeriğe ve kullanım yapısına ulaşmış olursunuz.
Kolay gelsin.
pl/sql de procedure, function overloading işlemi
Overload işlemi nedir ve neden ihtiyaç duyarız bunlara biz göz atalım ve pl/sql ile procedure ve function overload işlemi için hazırladığım örnek package kodlarımızı inceleyelim. Tabi overload deyince de aklımıza hemen yan taraftaki resim gibi izlenim oluşmasın. Bizim yapacağımız işlem kendi kontrolümüzde olacak ve yan taraftakine benzer bir senaryoya dönüşmeyecek.
Normal şartlar altında overload işlemine ihtiyacımız olmaz. Ama bazı durumlarda overload yapmamız gerekiyor. Örnek topla diye bir fonksiyon hazırladığımızı varsayalım ve bu fonksiyon içerisine aldığı iki değeri toplayıp bize geriye toplam sonucu döndürsün. Bu işlem sonrasında tekrardan bir toplama işlemine ihtiyacımız olduğunda bu sefer iki değil 3 ya da 4 sayıyı toplayıp bize sonucu döndüren bir fonksiyona ihtiyacımız olduğunda tekrardan yeni bir isim ile bu işlemi yapan fonksiyonu yazacaktık. Bunun yerine tüm fonksiyonların adı topla olsun ve ben içeriye kaç parametre gönderirsem sistem ilgili fonksiyonu kendisi çağırıp bana sonucu döndürsün. Böyle bir işlem yapınca overload işlemini gerçekleştirmiş oluyoruz.
Şimdi artık hazırladığım package ı kontrol edip birden fazla olan overload yöntemlerini ve örneklerimizi kontrol edelim. Pl/Sql ile overload işleminin prosedür için iki farklı yöntemi vardır;
- Prosedür içine gönderilen parametrenin tipine göre
- Prosedür içine gönderilen parametrelerin sayısına göre.
Bu işlem fonksiyon için iki değil üç farklı yöntem ile yapılır ve ilk iki yöntem prosedür ile aynıdır . Bu yöntemler;
- Fonksiyon içine gönderilen parametrenin tipine göre
- Fonksiyon içine gönderilen parametrelerin sayısına göre
- Fonksiyonun dönüş tipine göre
Artık pl/sql ile overload işlemini nasıl yapacağımızı öğrendiğimize göre örneklere geçebiliriz sanırım. Öncelikle package kodlarımızı ekleyelim ve sonrasında da bu package kullanımı ile örnek sonuçlarımızı kontrol edelim. Daha fazlasını oku…
pl/sql de zaman hesabı
Merhaba
Daha önce pl/sql de iki tarih arası farkı bulma hakkında bir makale yazmıştım. Şimdi bu makaleden farklı olarak pl/sql ile zaman hesabı yapabilmek için bir fonksiyon hazırladım. Çoğu zaman tarih ve saat hesabı ile ilgili işlemlere yazdığımız programlarda ihtiyacımız olmuştur. O durumlarda ihtiyaç doğrultusunda farklı çözümler ile bu sorunumuzu gidermişizdir fakat bu fonksiyon ile artık her ihtiyaç olduğunda yeni bir kontrol ya da fonksiyon yazmak yerine bu fonksiyonu kullanabilirsiniz.
Şimdi fonksiyonumuz oluşturalım ve örneklerimize bakalım.
CREATE OR REPLACE FUNCTION zaman_hesabi(tar DATE, islem VARCHAR2, tip VARCHAR2, deger NUMBER) RETURN VARCHAR2 IS sonuc DATE; BEGIN /* -- tar : işlem yapılacak tarih -- islem : '+' veya '-' -- tip : 'yy'=yıl; 'mm'=ay; 'dd'=gün; 'hh'=saat; 'mi'=dakika; 'ss'=saniye; -- deger : işlem yapılacak tarih için kullanılack değer */ IF islem = '+' THEN IF lower(tip) = 'yy' THEN sonuc := add_months(tar, 12 * deger); ELSIF lower(tip) = 'mm' THEN sonuc := add_months(tar, deger); ELSIF lower(tip) = 'dd' THEN sonuc := tar + to_dsinterval(deger || ' 00:00:00'); ELSIF lower(tip) = 'hh' THEN sonuc := tar + to_dsinterval('0 ' || deger || ':00:00'); ELSIF lower(tip) = 'mi' THEN sonuc := tar + to_dsinterval('0 00:' || deger || ':00'); ELSIF lower(tip) = 'ss' THEN sonuc := tar + to_dsinterval('0 00:00:' || deger); ELSE sonuc := tar; END IF; ELSIF islem = '-' THEN IF lower(tip) = 'yy' THEN sonuc := add_months(tar, 12 * (-deger)); ELSIF lower(tip) = 'mm' THEN sonuc := add_months(tar, (-deger)); ELSIF lower(tip) = 'dd' THEN sonuc := tar - to_dsinterval(deger || ' 00:00:00'); ELSIF lower(tip) = 'hh' THEN sonuc := tar - to_dsinterval('0 ' || deger || ':00:00'); ELSIF lower(tip) = 'mi' THEN sonuc := tar - to_dsinterval('0 00:' || deger || ':00'); ELSIF lower(tip) = 'ss' THEN sonuc := tar - to_dsinterval('0 00:00:' || deger); ELSE sonuc := tar; END IF; ELSE sonuc := tar; END IF; RETURN(to_char(sonuc, 'dd/mm/yyyy hh24:mi:ss')); END zaman_hesabi;
Artık fonksiyonumuz hazır. Şimdi bir sql ile bu fonksiyonun tüm değerlerini ve işlevselliğini kontrol edebiliriz.
SELECT 1 sira, 'Yıl Ekleme' islem, SYSDATE suanki_tarih, zaman_hesabi(SYSDATE, '+', 'yy', 1) deger_eklenen_tarih, zaman_hesabi(SYSDATE, '-', 'yy', 1) deger_cikan_tarih FROM dual UNION SELECT 2 sira, 'Ay Ekleme' islem, SYSDATE suanki_tarih, zaman_hesabi(SYSDATE, '+', 'mm', 1) deger_eklenen_tarih, zaman_hesabi(SYSDATE, '-', 'mm', 1) deger_cikan_tarih FROM dual UNION SELECT 3 sira, 'Gün Ekleme' islem, SYSDATE suanki_tarih, zaman_hesabi(SYSDATE, '+', 'dd', 1) deger_eklenen_tarih, zaman_hesabi(SYSDATE, '-', 'dd', 1) deger_cikan_tarih FROM dual UNION SELECT 4 sira, 'Saat Ekleme' islem, SYSDATE suanki_tarih, zaman_hesabi(SYSDATE, '+', 'hh', 1) deger_eklenen_tarih, zaman_hesabi(SYSDATE, '-', 'hh', 1) deger_cikan_tarih FROM dual UNION SELECT 5 sira, 'Dakika Ekleme' islem, SYSDATE suanki_tarih, zaman_hesabi(SYSDATE, '+', 'mi', 1) deger_eklenen_tarih, zaman_hesabi(SYSDATE, '-', 'mi', 1) deger_cikan_tarih FROM dual UNION SELECT 6 sira, 'Saniye Ekleme' islem, SYSDATE suanki_tarih, zaman_hesabi(SYSDATE, '+', 'ss', 1) deger_eklenen_tarih, zaman_hesabi(SYSDATE, '-', 'ss', 1) deger_cikan_tarih FROM dual;
Sql de hazır olduğuna göre sonuçlarımıza bakabiliriz.
SIRA | ISLEM | SUANKI_TARIH | DEGER_EKLENEN_TARIH | DEGER_CIKAN_TARIH |
---|---|---|---|---|
1 | Yıl Ekleme | 12.12.2012 09:28:38 | 12/12/2013 09:28:38 | 12/12/2011 09:28:38 |
2 | Ay Ekleme | 12.12.2012 09:28:38 | 12/01/2013 09:28:38 | 12/11/2012 09:28:38 |
3 | Gün Ekleme | 12.12.2012 09:28:38 | 13/12/2012 09:28:38 | 11/12/2012 09:28:38 |
4 | Saat Ekleme | 12.12.2012 09:28:38 | 12/12/2012 10:28:38 | 12/12/2012 08:28:38 |
5 | Dakika Ekleme | 12.12.2012 09:28:38 | 12/12/2012 09:29:38 | 12/12/2012 09:27:38 |
6 | Saniye Ekleme | 12.12.2012 09:28:38 | 12/12/2012 09:28:39 | 12/12/2012 09:28:37 |
Kolay gelsin.
pl/slq de fibonacci sayı dizisini oluşturma
Merhaba
Hayatında herkes Fibonacci sayı dizisini duymuştur. Bu konuda detaylı bilgi Leonardo Fibonacci linkinden ve özet ve basit bilgiyi ise Fibonacci Dizisi adresinden görebilirsiniz.
Bilindiği gibi Fibonacci dizisi bir matematiksel işlemdir. Herhangi bir programlama dili ile bu dizi rahatlıkla oluşturulabilinir.Fibonacci dizisinin temel formülü F(n-1)+F(n-2) şeklindedir. Pl/Sql ile de bir Fibonacci dizisi oluşturabiliriz.
DECLARE fibo VARCHAR2(4000); FUNCTION fibonacci(n NUMBER) RETURN NUMBER IS BEGIN IF n = 0 OR n = 1 THEN RETURN n; ELSE RETURN fibonacci(n - 1) + fibonacci(n - 2); END IF; END; BEGIN FOR i IN 0 .. 20 LOOP fibo := fibo || fibonacci(i) || ' '; END LOOP; dbms_output.put_line(fibo); END;
Ben örnek olarak 0-20 arasındaki sayılar için Fibonacci dizisi oluşturdum fakat bilindiği gibi Fibonacci dizisi herhangi bir sayıdan başlanılarak da oluşturulabilinir.
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
0-20 arasındaki sayılar için yukarıda gibi bir Fibonacci dizisi oluşurken bu işlemi 5-20 arasında yaparsak bahsettiğim herhangi bir sayıdan başlanıp Fibonacci dizi oluşturulduğunu ve değerlerin değişmediğini görelim.
DECLARE fibo VARCHAR2(4000); FUNCTION fibonacci(n NUMBER) RETURN NUMBER IS BEGIN IF n = 0 OR n = 1 THEN RETURN n; ELSE RETURN fibonacci(n - 1) + fibonacci(n - 2); END IF; END; BEGIN FOR i IN 5 .. 20 LOOP fibo := fibo || fibonacci(i) || ' '; END LOOP; dbms_output.put_line(fibo); END;
5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
Görüldüğü gibi dizide başlangıç değeri dışında değişen bir durum olmadı. Genel Fibonacci dizisi kuralı olan F(n-1)+F(n-2) durumu ile yazılım dili ne olursa olsun istenilen Fibonacci dizisi oluşturulabilinir.
NOT: Kodlarda da göreceğiniz gibi F(n-1)+F(n-2) işlemi yapmak için n>1 olması gerekiyor. n=1 ya da n=0 olduğu durumda kodlarda görülen işlemi yapmak n değerini olduğu gibi kullanmak gerekir.
Kolay gelsin.
pl/sql de metin içindeki karakter ya da sayısal değerleri bulma
Merhaba,
Database deki tablolarımız içerisinde kayıtlı olan karmaşık (karakter + sayısal değerler )verilerden sadece karakter içeriği ya da sayısal içeriği almak istediğimiz durumlar olabilir. Bu durumlarda küçük kod parçaları ile kontrol işlemleri yapmak yerine bu işlemi genelleştirip bir fonksiyon yardımı ile bu işlemi çözebiliriz. Bu durum için bir fonksiyon hazırlayalım.
CREATE OR REPLACE FUNCTION deger_bul(gelen_metin VARCHAR2, tip NUMBER) RETURN VARCHAR2 IS sonuc VARCHAR2(4000); tmp_deger VARCHAR2(10); tmp_number NUMBER; i NUMBER; BEGIN --tip=0 >> Karakter değerler --tip=1 >> Sayısal değerler sonuc := NULL; tmp_deger := NULL; IF gelen_metin IS NULL THEN RETURN NULL; END IF; FOR i IN 1 .. length(gelen_metin) LOOP IF tip = 0 THEN tmp_deger := substr(gelen_metin, i, 1); IF tmp_deger NOT IN ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') THEN sonuc := sonuc || tmp_deger; END IF; ELSIF tip = 1 THEN BEGIN tmp_deger := substr(gelen_metin, i, 1); tmp_number := to_number(tmp_deger); sonuc := sonuc || tmp_deger; EXCEPTION WHEN OTHERS THEN NULL; END; ELSE RETURN('Girien Tip İçin Bir Çalışma Yapılamaz.!'); END IF; END LOOP; RETURN sonuc; END deger_bul;
Hazırladığımız bu fonksiyon ile artık istediğimiz metin içinden istediğimiz veri setini alabiliriz. İster karakter içeriği , ister sayısal içeriği. Hemen bir örnek ile daha iyi bu durumu kavrayalım. Aşağıdaki script ile fonksiyonumuzun üç farklı duruma göre aynı anda çalıştırarak sonuçlarını görelim.
SELECT deger_bul('Bu Metin İçinden Sadece Karakter Değerleri Bulacak.1234567890', 0) karakter, deger_bul('Bu Metin İçinden Sadece Sayısal Değerleri Bulacak.1234567890', 1) sayisal, deger_bul('Bu İşlem İçin Doğru Tip Değeri Olmadığından Fonksiyon Hata Dönecek', 2) sonuc_yok FROM dual;
Fonksiyonu çalıştırdıktan sonra verdiğimiz tip değerlerine göre aldığımız sonuç aşağıdaki gibi olacaktır. Alınan sonuçtan da anlaşılacağı gibi sadece belirttiğimiz tip değerine göre sonuçlarımızı alabiliyoruz. Tanımlanan tip değeri dışında bir değer ile fonksiyon çalıştırıldığında açıklamalı olarak girilen tip için çalışma yapılmayacağı bilgisini vermiş oluyoruz.
KARAKTER | SAYISAL | SONUC_YOK |
---|---|---|
Bu Metin İçinden Sadece Karakter Değerleri Bulacak. | 1234567890 | Girien Tip İçin Bir Çalışma Yapılamaz.! |
Bu basit ve işlevsel fonksiyon daha ileri amaçlar için çeşitli değişiklikler ile daha da verimli hale getirilebilinir.
Kolay gelsin.