wtorek, 20 grudnia 2011

Ładowanie pliku do kolumny BLOB, CLOB

Zanim podejdziesz do tego artykułu, zapoznaj się z tym : http://andrzejklusiewicz.blogspot.com/2011/12/bfile-referencje-do-plikow-zewnetrznych.html
Wiedza z niego będzie Ci tutaj niezbędna.

Najpierw stwórz (o ile jeszcze nie masz) tabelkę z kolumną typu BLOB :

create table obrazki(
nr number,
obrazek blob
); 



Poniżej kod ładujący plik do kolumny typu danych blob w tabeli. Kilka linii niżej wyjaśnienie.





declare
plik bfile;
bl blob:=empty_blob();
wielkosc number;
nr number;
begin
plik:=bfilename('LOBY','obrazek3.jpeg');
if dbms_lob.fileexists(plik)=1 then
  wielkosc:=dbms_lob.getlength(plik);
  insert into obrazki values (moja.nextval,bl) returning nr, obrazek into nr, bl;
  dbms_lob.open(plik,dbms_lob.lob_readonly);
  dbms_lob.open(bl,dbms_lob.lob_readwrite);
  dbms_lob.loadfromfile(bl,plik, wielkosc);
  dbms_lob.close(bl);
  dbms_lob.close(plik);


  commit;
  dbms_output.put_line('plik znalazl się w tabeli pod numerem '||nr||', zajmuje '||wielkosc||' bajtow');
else dbms_output.put_line('nie znalazlem takiego pliku...'); 
end if;
end;



Pliki ładujemy do formatu BLOB za pośrednictwem formatu BFILE. Taka już uroda tego RDBMS...
Najpierw sekcja deklaracji.
plik bfile; - to będzie referencja do naszego pliku , zmienna plik będzie pośrednikiem w ładowaniu. Musi być typu bfile.
bl blob:=empty_blob(); - typ BLOB jest typem obiektowym, musimy więc użyć konstruktora do zainicjalizowania obiektu.

wielkosc number; - Do zmiennej wielkość trafi wielkość pliku w bajtach. Musisz mieć taką zmienną. Będzie niezbedna przy ładowaniu danych do  tabeli (przy procedure loadfromfile).

nr number; - nie jest konieczne, ja sobie taką zmienną zrobiłem by później do niej załadować wartość pod którą w kluczu głównym tabeli znajdzie się mój wiersz z obiektem blob.

Część wykonawcza:

plik:=bfilename('LOBY','obrazek3.jpeg'); - zmienną plik znanego już z artykułu poprzedniego typu danych bfile podpinamy pod istniejący plik. LOBY to alias katalogu (również omawiane w poprzednim rozdziale).

if dbms_lob.fileexists(plik)=1 - znane z poprzedniego rozdziału. Sprawdzam czy plik istnieje. Zwraca 1 albo 0.

wielkosc:=dbms_lob.getlength(plik); - znane z poprzedniego rozdziału. Pobieram wielkość pliku pod którego podpięta jest moja zmienna typu BFILE.

insert into obrazki values (moja.nextval,bl) returning nr, obrazek into nr, bl; - ładuję do tabeli na razie pusty obiekt BLOB, jednak jest on zwracany poprzez referencję. Taki wymóg konstrukcyjny...


dbms_lob.open(plik,dbms_lob.lob_readonly);
  dbms_lob.open(bl,dbms_lob.lob_readwrite);


Oba obiekty muszę otworzyć. Obiekt typu BFILE w trybie tylko do odczytu, obiekt BLOB w trybie do zapisu i odczytu.


  dbms_lob.loadfromfile(bl,plik, wielkosc); - Faktyczne ładowanie danych. Pierwszy parametr to zmienna typu BLOB (czyli obiekt docelowy) , druga to obiekt typu BFILE  (czyli obiekt źródłowy), trzecia to wielkość pliku który trzeba załadować. Czemu muszę mieć podpięty niejako "dwukrotnie" plik? Pamiętaj że BFILE trzymane są poza bazą a BLOB w niej.

  dbms_lob.close(bl);
  dbms_lob.close(plik);


Jak otworzyłem to muszę zamknąć. Jeśli tego nie zrobię to w końcu dostanę info że przekroczyłem dopuszczalną ilość otwartych referencji do plików.

commit; - Pamiętaj by zatwierdzić zapis. Dane generalnie po odpaleniu procedury loadfromfile znajdują się już w tabeli, niemniej jednak podlegają tranzakcyjności jak wszystkie inne dane.

 Możesz już korzystać ze swoich blobów :) Puść np. takie zapytanie:

select dbms_lob.getlength(obrazek) from obrazki;

 Generalnie  CLOBy ładuje się identycznie. Wszędzie gdzie tutaj wyżej pojawiło się BLOB, piszesz w to miejsce CLOB  :)

Brak komentarzy:

Prześlij komentarz