LISTAGG Fonksiyon İyileştirmeleri

Herkese Selam,

Bu yazıda, geliştirdiğimiz kodlar içerisinde sıkça kullandığımız LISTAGG fonksiyonu için Oracle 12c Release 2 ile beraber gelen iyileştirmelerden basedeceğim umarım farkındalık anlamında faydalı bir yazı olur.

LISTAGG fonksiyonu bilindiği üzere, SQL deyiminde verilmiş guruplama kriterine göre datanın ilgili kolonundaki değerleri tek bir satırda toplayan bir fonksiyon. Şimdi mevcut durumda nasıl çalıştığına bakalım.

Elimizde aşağıdaki gibi bir data olsun.

SELECT MOD (LEVEL, 4) grp, 
       LEVEL || '0000' AS col
FROM DUAL
CONNECT BY LEVEL < 10;







Şimdi bu datayı  GRP kolonuna göre gruplayıp, COL kolonundaki değerleri yan yana yazalım. (Bu işlemi gerçekleştirmek için LISTAGG kullanacağız.)

SELECT grp,
LISTAGG (col, '; ') 
WITHIN GROUP (ORDER BY col DESC) col
FROM (SELECT MOD (LEVEL, 4) grp, 
       LEVEL || '0000' AS col
       FROM DUAL
                                CONNECT BY LEVEL < 10)
                         GROUP BY grp;

Evet görüldüğü üzere LISTAGG fonksiyonu ile bu işi basitçe halledebildik. Şimdi sample veri setimizi biraz daha büyütüp sonucun dönüp dönmediğine bakalım.

SELECT grp, LISTAGG (col, '; ') WITHIN GROUP (ORDER BY col DESC) col
    FROM (    SELECT MOD (LEVEL, 4) grp, LEVEL || '0000' AS col
                FROM DUAL
          CONNECT BY LEVEL < 10000)
GROUP BY grp;

ORA-01489: result of string concatenation is too long

Datamızın büyüdüğü yani birleştirme işleminin büyük bir veri kümesi üzerinde yapılması gündeme geldiğinde yukarıdaki hatayı aldık ve işlemimize devam edemedik. İşte Oracle 12c R2 ile beraber gelen LISTAGG iyileştirmesi bu problemlere çareler üretmekte ve bu hataları almamızın önüne geçmekte.

Şimdi aynı sorguya 12c R2 ile beraber gelen ON OVERFLOW TRUNCATE söz deyimini ekleyerek çalıştıralım.

SELECT grp, LISTAGG (col, '; ' ON OVERFLOW TRUNCATE) 
WITHIN GROUP (ORDER BY col DESC) col
FROM ( SELECT MOD (LEVEL, 4) grp, LEVEL || '0000' AS col
FROM DUAL
CONNECT BY LEVEL < 10000)
GROUP BY grp;

Evet sorgumuz başarılı bir şekilde hata almadan sonlandı. Birleştirme sonucunda taşan kısım için … ibaresi koyuldu ve en sona truncate edilen toplan karakter sayısı yazıldı. Şimdi yapılan iyileştirme ile beraber gelen farklı opsiyonlara bakmaya devam edelim.

SELECT grp, LISTAGG (col, '; ' ON OVERFLOW TRUNCATE 'TAŞMA') 
WITHIN GROUP (ORDER BY col DESC) col
FROM ( SELECT MOD (LEVEL, 4) grp, LEVEL || '0000' AS col
FROM DUAL
CONNECT BY LEVEL < 10000)
GROUP BY grp;

Yukarıdaki örnekte ON OVERFLOW TRUNCATE söz deyiminden sonra taşan kısımda hangi ibarenin yazmasını istiyorsak onu belirtiyoruz ve sorguyu çalıştırıyoruz. Sorgu sonucunda belirttiğimiz ibarenin en sonda yer aldığını görmekteyiz.

 

 

 

Bir diğer kullanım opsiyonu ise en sonda truncate edilen karakter sayısının yazılmasını engellemek. Bunun içinde WITHOUT COUNT söz deyimini kullanıyoruz.

SELECT grp, LISTAGG (col, '; ' ON OVERFLOW TRUNCATE 'TAŞMA' 
WITHOUT COUNT) WITHIN GROUP (ORDER BY col DESC) col
FROM ( SELECT MOD (LEVEL, 4) grp, LEVEL || '0000' AS col
FROM DUAL
CONNECT BY LEVEL < 10000)
GROUP BY grp;

 

 

 

Evet görüldüğü üzere kesilen karakter sayısı belirtilmeyerek sonuç görüntülendi.

Sonuç olarak LISTAGG kullandığımız durumlarda taşma hataları ile karşılaşmak istemiyorsak, yeni gelen opsiyonları kullanmamız oldukça faydalı olacaktır.

 

Advertisements

About ... from Emrah METE

Bilgisayar Mühendisi
This entry was posted in Oracle, Uncategorized and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s