Etiketler

,


PL-SQL kodu ile sutunları birleştirmek için || karakterini CONCAT fonksiyonunu kullabilirsiniz. Peki satırları birleştirmenin bu kadar kolay bir yolu var mıdır?

Örneğin, bir kişi 1 den fazla yabancı dil biliyor olabilir. Join’lediğinizde, ilgili satıra karşılık N tane detay satırı gelecekten, tüm yabancı dillerini arasına sizin belirlediğiniz ayıracı koyarak tek satır olarak alsak ve bu sayede gereksiz yere kişinin diğer bilgilerini sorgu sonucunda tekrarlatmamak mümkün mü?

Yani, 1 den fazla değer dönen satırları, tekbir satır olarak alabilceğimiz genel bir fonksiyon var mıdır?

Bunun için PL_SQL’in hazır birkaç fonksiyonu mevcut. Kullanımı en kolay olan WM_CONCAT fonsiyonudur.

SELECT   wm_concat(ULKE.ULKE_TANIMI)  FROM   ULKE ;

Kullanımı ile Ulkeler tablosundaki tüm ülke isimlerini aralarında virgün (,) olacak şekilde tek bir satır halinde alabilirsiniz. Gayet kullanışlı ve kolay olmasına rağmen, bu fonksiyonun ufak bir kısıtı var. O da birleştireceğiniz metin boyutu 30k’yı geçtiğinde

ORA-22813 (operand value exceeds system limits. Cause: Object or Collection value was too large. The size of the value might have exceeded 30k in a SORT context, or the size might be too big for available memory.)

hatası vermesidir.

Yani ufak gündelik işlerinizde 30k‘ya ulaşabilmeniz olası bir durum değilken, büyük veritabanların büyük verilerinde ancak ve ancak veri tabanı parametrelerindeki 30k değerini arttırak işini görebilirsiniz. Tabiki bu parametreler ile oynamak hassas bir iştir. Bunun yerine, PL-SQL kodu ile detay tablodaki birden fazla satırı ana tablo’da tek bir satır olarak göstermek için aşağıdaki prosedürü kullanabilirsiniz.


CREATE OR REPLACE FUNCTION  SatirlariBirlesir (
sqlCumlesi     IN   VARCHAR2,
satirAyiraci   IN   VARCHAR2
— sqlCumlesi Varchar2 tipinde olmasının yanı sıra Varchar2 tipinde tek sutun getiren bir sorgu cümlesi olmalıdır.
satırAyiracı bu sorgu sonunda dönecek olan satırları, aralarına ne koyarak birleştireceğinin bilgisi
RETURN VARCHAR
IS
tekSatirTunKayitlar   VARCHAR2 (3000) := ”; — Fonksiyon sonunda dönen değer
csr                   sys_refcursor;
satirAyiracininUzunlugu NUMBER := LENGTH(satirAyiraci); — Ayıracın karakter sayısını atıyoruz.
   TYPE sutunTipi IS RECORD (
sutunIcerigi   VARCHAR2 (200)
);  — Varchar2 tipinde tek sutun getiren bir sorgu cümlesin sutunusutunKayitlari        sutunTipi; — sutunTipi tipinden değişken tanımlıyoruz.
BEGIN
OPEN csr FOR sqlCumlesi;  — SqlCumlesine için açtığımız CURSOR. LOOP  — sqlCumlesi sonucunda dönen tüm kayılar üzerinden döneceğiz.
FETCH csr
INTO sutunKayitlari; — CURSOR daki sutunTipi tipindeki veriyi sutunKayitlarının içine FETCH ediyoruz.EXIT WHEN csr%NOTFOUND;
tekSatirTunKayitlar :=
tekSatirTunKayitlar || satirAyiraci || sutunKayitlari.SutunIcerigi;  –– 1’den fazla dönen satıları birleştiriyoruz.
DBMS_OUTPUT.put_line (sutunKayitlari.SutunIcerigi);
END LOOP;

DBMS_OUTPUT.put_line (tekSatirTunKayitlar);

CLOSE csr;

tekSatirTunKayitlar := SUBSTR (tekSatirTunKayitlar, satirAyiracininUzunlugu +1 , LENGTH(tekSatirTunKayitlar)-satirAyiracininUzunlugu); — Kayıtların başına koyacağı gereksiz olan ayıracı temizliyouz.

RETURN tekSatirTunKayitlar; — N tane satırı 1 tane satır olarak geri döndürüyoruz.
END;


Bu konu ile ilgili çeşitli kaynaklar çok sayıda yaklaşım olmakla birlikte, en derli toplu çalışmayı, http://www.oracle-base.com/articles/misc/StringAggregationTechniques.php adresinde bulabilirsiniz.

Bu konu ile ilgili aşağıdaki yazıları okumanızı tavsiye ederim.

Teknik seviyesi biraz daha yüksek yazılar okuman isterseniz aşağıdaki yazılara göz atabilirsiniz.

Reklamlar