如何使用存储过程将文件读入Oracle DB

发布于 2024-11-19 14:35:18 字数 1589 浏览 3 评论 0原文

我正在尝试将文件作为 blob 读入我的 oracle 表中。该文件是*.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。

I'm trying to read a file into my oracle table as a blob. The file is *.gz data. I looked around the 'net and found some examples, and this is what I've come up with:

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;

When I run this, I get these errors:

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.

I've played around with the path various ways, ie '/tmp/', 'tmp', '/tmp'. The filename is correct, so I'm at a loss as to what's wrong. This is actually the first stored procedure I've ever written, so this might be a really simple thing. I hope someone can help me with this. I'm using Oracle SQL Developer, by the way.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

萧瑟寒风 2024-11-26 14:35:18

您需要 DBA 执行以下操作:

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

然后将 brian_tmp 替换为代码中的 /tmp/。 DBA 可能不想让您访问所有 /tmp (因为您的用户现在可以在该目录中伪装成运行 Oracle 的 Unix 用户执行任何操作),在这种情况下您将需要一个子目录。

You would need the DBA to do:

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

Then in place of /tmp/ in your code, you would put brian_tmp. The DBA might not want to give you access to all of /tmp (as your user can now do anything in that directory masquerading as the Unix user Oracle is running as) in which case you would need a subdirectory.

凌乱心跳 2024-11-26 14:35:18

您需要 DBA 在 Oracle 中创建 Directory 对象(而不是磁盘上的目录)。类似于:

CREATE DIRECTORY admin AS 'oracle/admin';

然后向目录授予权限;像其他模式对象一样(视图、包等...)

You need the DBA to create the Directory object in Oracle (not the directory on disk). Something like:

CREATE DIRECTORY admin AS 'oracle/admin';

Then permissions are granted to the directory; like other schema ojbects are (Views, packages etc...)

浅语花开 2024-11-26 14:35:18

除了其他答案之外,请注意,当您使用目录时,例如:

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';

In addition to the other answers, note that when you use your directory, e.g.:

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

The directory name must be in upper case unless specifically created in lower case via the use of double quotes in the CREATE statement:

CREATE DIRECTORY "My_Dir" AS '/tmp';

In which case you'd always have to refer to the name in double quotes in SQL, and in the proper case in programmatic refereces:

GRANT READ, WRITE ON DIRECTORY "My_Dir" TO this_user;
...
data_dir varchar2(20) := 'My_Dir';
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文