Arşiv

Posts Tagged ‘function’

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


overloadMerhaba,

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;

  1. Prosedür içine gönderilen parametrenin tipine göre
  2. 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;

  1. Fonksiyon içine gönderilen parametrenin tipine göre
  2. Fonksiyon içine gönderilen parametrelerin sayısına göre
  3. 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.