Oracle Bulk DELETE/UPDATE Islemleri

Oracle BULK Update/Delete islemleri

Oracle veritabaniniz da çok büyük tablolarda veri silmeniz/güncellemeniz gerekirse ihtiyaç duyacaginiz en önemli sey yüksek performanstir. Özellikle SOA veritabani yönetenlerin yasadiklari en büyük sorun çok yavas silme islemleridir. Tablolar sürekli büyür ve soa purge islemi yetersiz kalir. Sizde mecburen daha çok veri silmek için yöntemler düsünürsünüz. Iste bu durumda neredeyse herkes bulk islemlere yönelir ve bulk delete ile verilerini temizler. Bulk islemleri bir örnekle anlatmak istiyorum. Içine su doldurmaniz gereken büyük bir bidonunuz olsun bu bidonu sahil kenarina götürüp içine su dolduracaksiniz bidonunuzu denizden bardakla doldurmak normal islemdir fakat kovayla bidonu doldurmak bulk operasyondur. Kovayla hem daha kisa zamanda doldurursunuz hemde daha az yorulursunuz fakat bardakla doldurmak hem çok zaman alir hem de sizi ciddi manada yorar. Bu yüzden normal silme islemi büyük verilerde her zaman sorun olmustur. Tabiki operasyonunuz bulk isleme çevrilebilir bir operasyon olmalidir aksi taktirde bazi mantiksal operasyonlar bulk a çevrilemez böyle durumlarda beklemekten baska çareniz kalmaz.

BULK DELETE

.

Asagida örnegini verdigim bulk silme isleminizi kendi sorgunuza göre düzenleyebilirsiniz. Açiklamalari kodun içinde yapacagim.

CREATEORREPLACEPROCEDURE dlv_message_sil(prm_tarih DATE)
--silinecek veriler tarihe göre seçildigi için tarih parametresi eklendi 
IS 
	TYPE t_id_list ISTABLEOFROWID;
	-- tabloda verileri rowid ye göre silecegiz ve rowid leri 
    --tutmak için tanimlayacagimiz degiskene verecegimiz veri tipi 
	
	lBulkSize NUMBERDEFAULT50000;
	--kayitlari kaçar kaçar silecegiz kovanin büyüklügünü burada 
    --belirlemis oluyoruz 
	
	id_list t_id_list;
	-- yukarida tanimladigimiz tipi bir degisikene atadik. 
	
	CURSOR c_dvl_message ( 
	--- bu cursor ile silecegimiz kayitlarinin tümünü bir defalik çekiyoruz 
	
	p_tarih DATE) 
	IS 
		SELECT/*+ parallel(t,16) */ 
		t.ROWID 
		FROM ttoprod_soainfra.dlv_message t 
		where trunc(receive_date) <trunc(p_tarih); 
	
	BEGIN 
		OPEN c_dvl_message (prm_tarih);
		-- cursoru çagirip kayitlari topluyoruz 
		
		LOOP 
			FETCH c_dvl_message 
			-- belirledigimiz limit kadar kayidi toplayip id_list 
            --degiskenine aliyoruz 
			
			BULKCOLLECTINTO id_list 
			LIMIT lBulkSize; 
			EXITWHEN id_list.COUNT=0;
			-- id_list e atilacak kayit kalmadiginda yani tüm kayitlar 
			--bittiginde loop dan çikiyoruz 

			FORALL indx IN id_list.FIRST.. id_list.LAST
			-- id_list içindeki kayitlari siliyoruz 
			
			DELETEFROM ttoprod_soainfra.dlv_message t 
			WHEREt.ROWID= id_list (indx); 
			COMMIT; 
		ENDLOOP; 
		CLOSE c_dvl_message;
		-- silme islemi bittigi için cursor i kapatiyoruz 
		
		EXCEPTION 
			WHENOTHERS 
		THEN 
			ROLLBACK; 
		executeimmediate'insert into hatalar values('''SQLERRM''')';
		--eger hata alirsa hatalar tablosuna kayit atiyoruz. 
		
			COMMIT; 
	END;
    

BULK DELETE

.
DECLARE 
lBulkSize NUMBERDEFAULT5000;
-- ne kadar datayi ayni anda update edecegimiz 

CURSOR c_data --- update edecegimiz verileri topluyoruz 
IS 
	SELECT /*+ parallel(t1,8) parallel(t2,8) */ 
	COUNT(1)AS coun, 
	SUM(t1.alan2) tutar, 
	t1.alan1 anahtar 
	FROM TEST1 t1, TEST2 t2 
	WHERE t1.id=t2.id 
	GROUPBY t1.alan1; 

TYPE t_num_array ISTABLEOFNUMBER 
INDEXBYBINARY_INTEGER;
-- toplayadigimiz verileri atacagimiz degisken için veri tipi 

TYPE t_char_array ISTABLEOFVARCHAR2(100) 
-- toplayadigimiz verileri atacagimiz degisken için veri tipi 

INDEXBYBINARY_INTEGER; 

deger1 t_num_array;
-- verileri atacagimiz degiskeni tanimliyoruz 

deger2 t_num_array;
-- verileri atacagimiz degiskeni tanimliyoruz 

deger3 t_num_array;
-- verileri atacagimiz degiskeni tanimliyoruz 

BEGIN 
OPEN c_data;--verileri toplamak için cursor i açiyoruz 

LOOP 
	FETCH c_data 
	-- yukarda topladigimiz verileri belirledigimiz miktarda 
    --degiskenlere atiyoruz 
	
	BULKCOLLECTINTO deger1, deger2, deger3 
	LIMIT lBulkSize; 

	EXITWHEN deger3.COUNT=0;
	--deger3 anahtar oldugu için onu seçtim ve veri bitince döngüden 
    --çikmasini sagladim 
	
	FORALL i IN1.. deger3.COUNT 
	-- kayitlari güncelliyoruz 
	
	UPDATE guncellenecek_tablo t1 
	SET t1.guncel1 = deger1(i) 
	, t1.guncel2 = deger2(i) 
	WHERE t1.id= deger3(i); 
	COMMIT; 
ENDLOOP; 
-- buraya exception koyup hatalar kayit altina 
--alinabilir. yukaridaki örnekten alabilirsiniz 
DBMS_OUTPUT.put_line ('islem basarili'); 
CLOSE c_data;--- cursor u kapatmayi unutmuyoruz 
END; 
.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir