PL/SQL File to Blob
Merhaba,
Bir dosyayı BINARY olarak veritabanına yazmak günümüz yazılım uygulamalarında önemli bir ihtiyaç olarak önümüze çıkmaktadır. Bu yazıda sistem üzerinde bulunan dosyayı BLOB bir tablo alanına yazma yönteminden bahsedeceğim. Oracle veritabanında LOB (Large Object) veri tipi BINARY olarak BLOB (Binary Large Object) ve karakter olarak CLOB (Character Large Object) tutulmaktadır. VARCHAR2 veri tipinin 4000 BYTE’ı aştığı durumlarda veriyi tabloda CLOB olarak tutmak çözüm sağlamaktadır. Aynı şekilde resim, doküman gibi karakter olmayan veri tiplerini de BINARY olarak tutmak için BLOB veri tipini kullanmalıyız.
BLOB veri tipi başka bir karakter veya BLOB veri tipinden doldurulabileceği gibi sistem üzerinde bulunan bir dosyadan da doldurulabilir.
Sistem üzerindeki bir dosyayı BLOB alana yazmak için aşağıdaki adımların pl/sql koduna dökülmesi gerekmektedir;
- Dosyanın tutulduğu dizinin karşılığına denk gelen DIRECTORY objesi Oracle veritabanında oluşturulur.
- Hedef BLOB ve kaynak BFILE değişkenleri tanımlanır.
- İlgili tabloya BLOB alanı boş olacak şekilde satır INSERT edilir.
- Tablodaki BLOB alan hedef değişkene aktarılır.
- BLOB ve BFILE LOB’ları açılır.
- BFILE kaynak değişkeni BLOB hedef değişkenine LOAD edilir.
- Kullanılan bütün LOB objeleri kapatılır.
- COMMIT çalıştırılır.
Öncelikle tablomuzu aşağıdaki SCRIPT’i kullanarak oluşturuyoruz;
1 2 3 4 5 6 7 8 9 10 11 12 13 |
create table xx_oracle_text_ornek ( sira_id number, dokuman blob, kayit_tarihi date ); alter table hr.xx_oracle_text_ornek add constraint xx_oracle_text_ornek_pk primary key (sira_id); |
Veritabanı üzerinde DIRECTORY oluşturuyoruz.
Not: Bu script sistemininizde olmayan dizinleri yaratmaz. DIRECTORY’nin anlamı sisteminizde bulunan bir dizinin Oracle Veritabanındaki karşılığıdır.
1 2 3 |
create or replace directory xx_win_anil_dir as 'c:\blog'; |
Hedef BLOB ve kaynak BFILE değişkenleri tanımlanır;
1 2 3 4 5 |
declare l_blob_dosya blob; l_dosya bfile := bfilename('XX_WIN_ANIL_DIR', 'a.pdf'); |
Tabloya empty_blob() içeren bir satır INSERT edilir. Bu noktada DML operasyonunda return into kullanılmıştır. return into DML operasyonundan hemen sonra ilgili alanı değişkene atar. Comment içine aldığım kısım ile aynı işlevi görür. Eğer Comment’li kısmı kullanacaksanız returning into cümlesini kaldırınız.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
begin insert into xx_oracle_text_ornek ( sira_id, dokuman, kayit_tarihi ) values ( 1, empty_blob(), sysdate ) returning dokuman into l_blob_dosya; /*select dokuman into l_blob_dosya from xx_oracle_text_ornek where sira_id = 1;*/ |
LOB objeleri DBMS_LOB yardımı ile OKUMA veya OKUMA_YAZMA modunda açılır.
1 2 3 4 |
dbms_lob.open(l_dosya, dbms_lob.lob_readonly); dbms_lob.open(l_blob_dosya, dbms_lob.lob_readwrite); |
LOB objeleri arası aktarım gerçekleştirilir.
1 2 3 4 5 |
dbms_lob.loadfromfile(dest_lob => l_blob_dosya, src_lob => l_dosya, amount => dbms_lob.getlength(l_dosya)); |
Kullanılan LOB objeleri kapatılır ve COMMIT çalıştırılır.
1 2 3 4 5 6 |
dbms_lob.close(l_dosya); dbms_lob.close(l_blob_dosya); commit; |
Bütün Kod;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
declare l_blob_dosya blob; l_dosya bfile := bfilename('XX_WIN_ANIL_DIR', 'a.pdf'); begin insert into xx_oracle_text_ornek ( sira_id, dokuman, kayit_tarihi ) values ( 1, empty_blob(), sysdate ) returning dokuman into l_blob_dosya; /*select dokuman into l_blob_dosya from xx_oracle_text_ornek where sira_id = 1;*/ dbms_lob.open(l_dosya, dbms_lob.lob_readonly); dbms_lob.open(l_blob_dosya, dbms_lob.lob_readwrite); dbms_lob.loadfromfile(dest_lob => l_blob_dosya, src_lob => l_dosya, amount => dbms_lob.getlength(l_dosya)); dbms_lob.close(l_dosya); dbms_lob.close(l_blob_dosya); commit; end; |