ORQACLE 9.2i BFILE- funkcie

Kluvanek Martin kluvanek na tesnet.cz
Středa Červenec 30 21:28:14 CEST 2003


Odpovedam si sam

Riesenie domaceho ukolu (mozno ze to niekomu usetri nechutne vyskumy):

Boli tam pekne 2 hacky.
1)uzivatel SYSTEM musi grantovat prava na ALIAS (DIRECTORY) nielen 
ROLIAM (skupinam) ale i konkretnym uzivatelom, ktori vlastnia objekty 
(TABLE,VIEW, mozno i FUNCTION) ktore chcu pristupovat k datam v BFILE.
Cize som tam musel grantnut 1 konkretneho uzivatela (a nie role).
pretoze VIEW ktory k datam chcel pristupovat patril jemu, i ked ten VIEW 
pouziva napriklad uplne iny uzivatel (ktory vyslovny GRANT na DIRECTORY 
na svoje meno nepotrebuje)....
2)Nesmiem sa spytat na filesize pokial je ten BFILE=NULL a este k tomu 
ani ked subor v skutocnosti neexistuje (fileexists=0)

Ukazky:
-- toto sa musi ako SYSTEM:
create directory BFILE_TESTdir AS 'E:\MSE\ANA-MU\DATA';
GRANT READ ON Directory BFILE_TESTDIR TO 
MSEACCESS,MSEadmin,MSEmereni,MSEwebinterface;
-- tak tento grant nestaci i ked uzivatel MSE ma priradenu rolu MSEadmin

-teraz sa prihlasit ako iny uzivatel (u mna MSE) a
create table Bfile_test
(  ZAZNAM_ID        NUMBER(38) not null,
   DATA             BFILE);

--naplneni daty
-nutno predtim na ORACLE servru nahrat ukazkove soubory do adresare 
aliasu BFILE_TESTDIR.
INSERT INTO Bfile_test (zaznam_ID,DATA) values
(1,BFILENAME('BFILE_TESTDIR','#test1.txt'));
INSERT INTO Bfile_test (zaznam_ID,DATA) values
(2,BFILENAME('BFILE_TESTDIR','#test2.txt'));
INSERT INTO Bfile_test (zaznam_ID,DATA) values
(3,BFILENAME('BFILE_TESTDIR','test\#test1x.txt'));
INSERT INTO Bfile_test (zaznam_ID,DATA) values
(4,BFILENAME('BFILE_TESTDIR','test\#test2x.txt'));
commit;

-- ============ Teraz nadefinovat funkcie ================
create or replace function BFILE_FILEEXISTS(BLO in BFILE) return number is
   Result number;
    v number;
begin
   result:=0;
   if blo is null then
     result:=-1;
   else
       v:=SYS.DBMS_LOB.fileexists(blo);
      result:=v;
   end if;
   return(Result);
end BFILE_FILEEXISTS;
/

create or replace function BFILE_FILESIZE(BLOK in BFILE) return number is
   Result number;
begin
result:=bfile_fileexists(BLOK);
if result<=0 then
    result:=-1;
else
    result:=SYS.DBMS_LOB.getlength(blok);
end if;
return(Result);
end BFILE_FILESIZE;
/

-- ============ A teraz nejaky ten pohlad ================
create or replace view pohled_blob_zaznam as
select
       zaznam_ID,
       BFILE_ISNULL(BL.DATA) as DATA_ISNULL,
       BFILE_FILEEXISTS(BL.DATA) as DATA_FILEEXISTS,
       BFILE_FILESIZE(BL.DATA) as DATA_FILESIZE,
       BFILE_GET_DIR(BL.DATA) as DATA_FILE_DIR,
       BFILE_GET_FILENAME(BL.DATA) as DATA_FILENAME
from Bfile_test  BL;

=============================================================
1)Uff, je to pekne hnusne pretoze ked nepriradite tie prava vlastnikovi 
pohladu tak view nebude fungovat ale testovaci script PL/SQL ano. (aspon 
v mojom vyvojovom prostredi)
2) Ked subor na disku premenujete alebo zmazete, tak 
SYS.DBMS_LOB.getlength padne na hubu....

Niesom si isty, ci tonieje chybka v oracle pretoze napriklad procedura 
SYS.DBMS_LOB.FILEGETNAME funguje OK i ked subor neexistuje....
Ale zas na druhu stranu to je i celkom logicke (viem, kam mam ten subor 
zas podvrhnut)

HOWGH!


Kluvanek Martin wrote:
> Pomooc.
> Uz opravdu netusim, kde robim chybu.
> Netusite nahodou niekto, kde je zrada?
> Napisal som si funkciu
> create or replace function BFILE_FILESIZE(BLOK in BFILE) return number is
>   Result number;
> begin
>   result:=0;
>   if blok is null then
>     result:=0;
>   else
>      result:=SYS.DBMS_LOB.getlength(blok);
>   end if;
>   return(Result);
> end BFILE_FILESIZE;
> 
> Spravil som si testovaci program
> 
> declare
>   da bfile;
>   v number;
> begin
>   select data into da from blob_zaznam where zaznam_id=1006;
> if da is null then
>   sys.dbms_output.put_line('NULL');
> else
>     v:=SYS.DBMS_LOB.getlength(da);
>     sys.dbms_output.put_line('len1=' ||to_char(v));
>     v:= BFILE_FILESIZE(da);
>     sys.dbms_output.put_line('len2=' ||to_char(v));
> end if;
> end;
> 
> 
> Ked to spustim (id 1006 ukazuje na korektny nenulovy zaznam)
> tak sa vypise len1=nejake cislo (spravne)
> a vo volani BFILE_FILESIZE to vsak padne na prikaze    
>    result:=SYS.DBMS_LOB.getlength(blok);
> ORA-22285:pro operaci GETLENGHT neexistuje adresar nebo soubor.
> 
> ???preco volanie jednej a tej istej funkcie ide z testovacieho sql ok a 
> z funkcie nie?
> Pricom DBMS_LOB.FILEGETNAME vracia spravne
> dir="MSE_ANALOGDATA" file="2B\Gen2#.tes"
> DBMS_LOB.fileexists =1
> DBMS_LOB.getlength=5466
> DBMS_LOB.fileopen funguje....
> 
> Pokial je BFILE null, tak to funguje spravne (vrati 0).
> Takto nefunguje GetLength, Fileexists
> ale funguje FILEGETNAME... (procedura)...
> 
> Dokonca i vovnutri v BFILE_FILESIZE ked to vysperkujem i FILEGETNAME tak 
> FILEGETNAME vrati rozumne hodnoty a GETLENGTH zhavaruje.....
> 
> 
> Pomoooc :-(
> 
> 
> 


-- 
Martin Kluvanek
ved.odd. vyvoje (head of development department)
TES s.r.o
Testovani Energetickych Systemu (Testing of Energetical Systems)

Prazska 597
674 01 Trebic
Czech republic
tel:568 8384 28  (+420 5688384 28)
fax:568 8384 27  (+420 5688384 27)
homepage: http://www.tesnet.cz



Další informace o konferenci Databases