wtorek, 13 grudnia 2011

BFILE. Referencje do plików zewnętrznych w Oracle

Czołem,
dziś na tapetę bierzemy typ danych BFILE. Jest to typ służący do przetrzymywania referencji do plików przetrzymywanych poza bazą. Zapytacie , na co komu taki rodzaj danych skoro można przechowywać ścieżkę do pliku w zwykłym varcharze? BFile pozwoli nam np. sprawdzić czy plik istnieje, jaką ma wielkość , porównać dwa pliki.

Początek

Ponieważ BFile trzyma referencję do plików zewnętrznych, stwórz sobie najpierw katalog na dysku, a następnie wrzuć do niego parę plików (wszystko jedno jakich).











Mój katalog znalazł się pod ścieżką "C:\loby".  Następnie {!} z poziomu sysa {!} tworzymy sobie obiekt directory który pozwoli nam na dostęp do tego katalogu z poziomu Oracle. Należy też nadać uprawnienia do korzystania z tego katalogu użytkownikowi z poziomu którego mamy zamiar z tych plików korzystać:

create directory loby as 'c:\loby';
grant read, write on directory loby to testowy;





Ja nadałem uprawnienia użytkownikowi "testowy", a mój katalog w Oracle będzie widoczny pod nazwą "loby".

Sprawdzanie czy plik istnieje

Teraz sprawdzę czy wskazany przeze mnie plik istnieje:




Declare
plik bfile;
Begin
Plik:=Bfilename('LOBY','oko.jpeg');
If Dbms_Lob.Fileexists(Plik)=1 Then
     Dbms_Output.Put_Line('jest taki plik!');
Else Dbms_Output.Put_Line('pliku niet!');
end if;
end;






Wykorzystałem tutaj procedurę fileexists z pakietu dbms_lob. Zwraca ona wartość 0 lub 1 w zależności od
tego czy plik istnieje czy nie. Funkcja (?) bfilename podpina referencję do pliku "oko.jpeg" znajdującego się w katalogu o aliasie "loby" (c:\loby) do na razie jeszcze pustej zmiennej plik. Pamiętać należy by alias katalogu podawać zawsze dużymi literami. Jak widzimy plik o który zapytałem istnieje.


Sprawdzanie wielkości

Poszerzmy teraz nasz test. Sprawdzimy , jeśli istnieje to jaką ma wielkość:




Declare
plik bfile;
Begin
Plik:=Bfilename('LOBY','oko.jpeg');
If Dbms_Lob.Fileexists(Plik)=1 Then
     Dbms_Output.Put_Line('jest taki plik!');
     Dbms_Lob.Fileopen(Plik);
     Dbms_Output.Put_Line('ten plik ma '||Dbms_Lob.Getlength(plik)||' bajtów');
     dbms_lob.fileclose(plik);
Else Dbms_Output.Put_Line('pliku niet!');
end if;
end;





Taki plik możemy otworzyć przy użyciu procedury fileopen z pakietu dbms_lob. Skoro otworzyliśmy to musimy go po wszystkim zamknąć  (dbms_lob.fileclose).
Do sprawdzenia wielkości służy nam procedura getlength z pakietu dbms_lob.
Gdyby Oracle rzucał nam wyjątkiem dotyczącym liczby otwartych plików, należy zmodyfikować parametr session_max_open_files określający ile możemy mieć jednocześnie podpiętych i otwartych plików w sesji.


Przechowywanie

Takie dane  (typu bfile) przechowywać mogę również w tabelkach. Na początek tworzymy sobie tabelkę z kolumną bfile. Przy okazji tworzę też sekwencję która będzie mi za moment potrzebna. Tych dla których pojęcie sekwencji jest nowością odsyłam do rozdziału "sekwencje" w znajdującym się na tej stronie kursie SQL.

Create Table Obrazki (
Nr Number Primary Key,
obrazek bfile
);

Create Sequence Moja
Start With 1 Increment By 1;







Dalej dodaję wiersze do tej tabeli:


insert into obrazki values (moja.nextval, bfilename('LOBY','aniol.jpg') );
insert into obrazki values (moja.nextval, bfilename('LOBY','smerfy.jpg') );
commit;





Na podobnej zasadzie odbywa się update - muszę wykorzystać poznaną już w tym rozdziale funkcję (?) bfilename.
Jeśli na takiej tabeli wykonam select , niewiele uzyskam informacji:




Mogę jednak posługując się funkcjami z pakietu dbms_lob poszerzyć swój zasób wiedzy np.
dowiadując się jaką ma wielkość:








BFILE w PLSQL i sprawdzanie ścieżki

Przy użyciu PL/SQL również mogę obsługiwać taki typ danych. Poszerza to również możliwości o weryfikację nazwy pliku i aliasu katalogu w którym znajduje się plik:



declare
plik bfile;
nazwapliku varchar2(50);
katalog varchar2(50);
begin
select obrazek into plik from Obrazki where nr=2;
dbms_output.put_line('wielkość pliku: '||Dbms_Lob.Getlength(plik));
dbms_lob.filegetname(plik,katalog,nazwapliku);
dbms_output.put_line('plik nazywa się: '||nazwapliku);
dbms_output.put_line('plik znajduje się w katalogu: '||katalog);
end;





Poszerza, ponieważ wykorzystuję procedurę filegetaname (która jest przecież procedurą więc nie mogę jej wykorzystywać w SQLu) która wykorzystuje parametry typu OUT. Zwraca do nich (nazwapliku,katalog) żądane informacje.  Zwracana jest nazwa aliasu, ale jeśli chcesz poznać dokładną ścieżkę to możesz przeszukać słownik all_directories w poszukiwaniu dokładnych informacji na temat danego katalogu.


cdn...

Brak komentarzy:

Prześlij komentarz