Как использовать хранимую процедуру для чтения файла в оракул БД - PullRequest
2 голосов
/ 12 июля 2011

Я пытаюсь прочитать файл в мою таблицу оракулов в виде большого двоичного объекта.Файл данных * .gz.Я посмотрел в сети и нашел несколько примеров, и вот что я придумал:

create or replace PROCEDURE upload_supp_data
IS
   src_file   BFILE;
   dst_file   BLOB;
   lgh_file   BINARY_INTEGER;
   data_dir varchar2(20) := '/tmp/';
   file_name varchar2(50) := '200912020200.rep-ids-top50-sip.txt.gz';
BEGIN

   src_file := BFILENAME (data_dir, file_name);

   -- insert a NULL record to lock
   INSERT INTO alarms_supplemental
               (alarm_id, resource_id, supplementaldata
               )
        VALUES (13794740, 1, EMPTY_BLOB ()
               )
     RETURNING supplementaldata
          INTO dst_file;

   -- lock record
   SELECT  supplementaldata
         INTO dst_file
         FROM alarms_supplemental
        WHERE alarm_id = 13794740
   FOR UPDATE;

   -- open the file
   DBMS_LOB.fileopen (src_file, DBMS_LOB.file_readonly);
   -- determine length
   lgh_file := DBMS_LOB.getlength (src_file);
   -- read the file
   DBMS_LOB.loadfromfile (dst_file, src_file, lgh_file);

   -- update the blob field
     UPDATE ALARMS_SUPPLEMENTAL
      SET supplementaldata = dst_file
    WHERE ALARM_ID = 13794740;

   -- close file
   DBMS_LOB.fileclose (src_file);
END upload_supp_data;

При запуске я получаю следующие ошибки:

ORA-22285: non-existent directory or file for FILEOPEN operation

ORA-06512: at "SYS.DBMS_LOB", line 635

ORA-06512: at "AIP_DBA.UPLOAD_SUPP_DATA", line 29

ORA-06512: at line 2

Process exited.

Я поиграл с путями разными способами, то есть '/ tmp /', 'tmp', '/ tmp'.Имя файла правильное, поэтому я не понимаю, что не так.На самом деле это первая хранимая процедура, которую я когда-либо написал, так что это может быть очень простой вещью.Я надеюсь, что кто-то может помочь мне с этим.Кстати, я использую Oracle SQL Developer.

Ответы [ 3 ]

4 голосов
/ 13 июля 2011

Вам потребуется, чтобы администратор БД:

CREATE DIRECTORY brian_tmp AS '/tmp';
GRANT READ, WRITE ON DIRECTORY brian_tmp TO brian;

Тогда вместо /tmp/ в вашем коде вы бы поставили brian_tmp.Администратор базы данных может не захотеть предоставлять вам доступ ко всем /tmp (поскольку ваш пользователь теперь может делать что-либо в этом каталоге, маскируясь под пользователем Unix, под которым работает Oracle), в этом случае вам потребуется подкаталог.

3 голосов
/ 12 июля 2011

Вам нужен администратор базы данных для создания объекта каталога в Oracle (не каталога на диске). Что-то вроде:

CREATE DIRECTORY admin AS 'oracle/admin';

Тогда разрешения выдаются для каталога; как и другие объекты схемы (Представления, пакеты и т. д.)

2 голосов
/ 13 июля 2011

В дополнение к другим ответам, обратите внимание, что при использовании вашего каталога, например ::

CREATE DIRECTORY my_dir as '/tmp';
GRANT READ, WRITE ON DIRECTORY my_dir TO this_user;
...
data_dir varchar2(20) := 'MY_DIR';

Имя каталога должно быть в верхнем регистре, если только оно не было специально создано в нижнем регистре с использованием двойных кавычек в операторе CREATE:

CREATE DIRECTORY "My_Dir" AS '/tmp';

В этом случае вам всегда нужно ссылаться на имя в двойных кавычках в SQL, а в правильном случае в программных ссылках:

GRANT READ, WRITE ON DIRECTORY "My_Dir" TO this_user;
...
data_dir varchar2(20) := 'My_Dir';
...