【问题标题】:How to solved problem with Oracle DBMS_LOB如何解决 Oracle DBMS_LOB 的问题
【发布时间】:2020-06-12 22:10:46
【问题描述】:

我正在尝试将 XML 文件的信息保存在数据库表中,并且我正在使用以下过程:

create or replace PROCEDURE P_FILEUPLOAD_XML (P_CMTT_CODE IN NUMBER DEFAULT 15, P_TEXT IN VARCHAR2, P_TEXT_NAR IN VARCHAR2, P_PATH IN VARCHAR2, P_FILENAME IN VARCHAR2, P_RET_VAL OUT NUMBER) IS

GRUPO       VARCHAR2(20);
l_dir       CONSTANT VARCHAR2(35) := P_PATH;
l_fil       CONSTANT VARCHAR2(30) := P_FILENAME; 
l_loc       BFILE; -- Pointer to the BFILE
l_ret       BOOLEAN := FALSE; -- Return value
l_pos       NUMBER := 1; -- Current position in the file (file begins at position 1)
l_sum       number default 8000; -- Amount of characters have been read
l_buf       VARCHAR2(32767); -- Read Buffer
l_sen       CONSTANT RAW(100) := UTL_RAW.CAST_TO_RAW(CHR(10)); -- Character at the end of the file is NEWLINE (ascii = 10)
l_end       NUMBER; -- End of the current word which will be read
l_counter NUMBER := 0; -- Counter for line sequence
l_line      VARCHAR2(32767); -- Contains the info line by line for insert

BEGIN

SELECT TEXTO INTO GRUPO FROM gzvcatg
         UNPIVOT ((codigo, texto) FOR gzvcatg_external_code IN (
            (gzvcatg_external_code1, gzvcatg_desc1) AS '1')
         WHERE GZVCATG_GROUP = 'TIT_ELEC'
            AND CODIGO = 'PATH';

     -- Mapping the physical file with the pointer to the BFILE
        l_loc := BFILENAME(GRUPO,'ES0000251446027471.xml');

    -- Open the file in READ_ONLY mode
       DBMS_LOB.OPEN(l_loc,DBMS_LOB.LOB_READONLY);
       LOOP
          l_counter := l_counter + 1; -- Counter for sequence
          -- Calculate the end of the current word
          l_end := DBMS_LOB.INSTR(l_loc,l_sen,l_pos,1);

          -- Process end-of-file
          IF (l_end = 0) THEN
            l_end := DBMS_LOB.INSTR(l_loc,l_sen,l_pos,1);
            l_sum := l_end - l_pos - 1;
            EXIT;
          END IF;

          -- Read until end-of-file
          l_sum := l_end - l_pos;
          DBMS_LOB.READ(l_loc,l_sum,l_pos,l_buf);
          l_line := UTL_RAW.CAST_TO_VARCHAR2(l_buf);

        BEGIN 
            INSERT INTO SPRCMNT (
                         SPRCMNT_CMTT_CODE,
                         SPRCMNT_TEXT,
                         SPRCMNT_TEXT_NAR)
                                VALUES(P_CMTT_CODE,
                                       P_TEXT,
                                       P_TEXT_NAR);    
             EXCEPTION WHEN OTHERS THEN 
             ROLLBACK;           
        END;
    END LOOP;    
EXCEPTION
    WHEN OTHERS THEN
        dbms_output.put_line('Error:' || SQLERRM);
        DBMS_LOB.CLOSE(l_loc);
        P_RET_VAL := 3;
        dbms_output.put_line('P_RET_VAL:' || P_RET_VAL);    
END;

但是当我执行该过程时,我收到以下错误:

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

如果我的 XML 文件存在,我不明白为什么路径 C:\XMLS\ 确实存在。

我得到了带有查询结果的路线。

这个查询的结果被赋值给了一个名为GRUPO的变量,这是我在过程开始时声明的,然后我把这个变量作为参数放在函数BFILENAME中,它最初包含directory y filename。可以看文档BFILENAMEhere

l_loc := BFILENAME(GRUPO,'ES0000251446027471.xml');

除此之外,我还在 Oracle 中创建了一个目录,如下所示:

CREATE OR REPLACE DIRECTORY DIR_XML as 'C:\XMLS\';

我也给了目录权限

GRANT ALL ON DIRECTORY DIR_XML TO PUBLIC;

我在这个问题上浪费了很多时间,但我找不到任何解决方案。任何帮助将不胜感激。

【问题讨论】:

  • 目录 "C:\XMLS\" 存在于您的 数据库服务器 上,对吗?本地硬盘上的“C:\XMLS\”目录不起作用。
  • 该目录存在于我的本地硬盘上
  • 当您在数据库服务上运行 PL/SQL 块时,文件访问将查看数据库服务器上的驱动器。那是你的问题。

标签: oracle plsql procedure


【解决方案1】:

来自the documentation you linked to:

  • 'directory' 是一个数据库对象,用作文件实际所在的服务器文件系统上的完整路径名的别名。

所以GRUPO 应该评估为'DIR_XML' 而不是'C:\XMLS'。该文档中的示例显示了这一点。 (有一个旧的基于存储为数据库参数的路径的预目录对象机制,但安全性较低......)

如果你只有路径,你可以查找目录名称:

select directory_name from all_directories where directory_path = 'C:\XMLS'

请记住,目录路径不必是唯一的,因此您可能必须处理重复项。

但正如@Matthew 已经解释的那样,以及as the documentation says(已添加重点):

目录对象指定服务器文件系统上的目录的别名,其中...

数据库只能查看其自己的文件系统(本地或共享)上的文件,而不能查看客户端文件系统上的文件。如果您也在本地运行数据库,那么没有区别(尽管目录和文件权限仍然很重要)。如果您正在访问远程数据库,那么它看不到您的客户端 C: 驱动器,并且如果您提供目录对象名称,您仍然会得到如下内容:

ORA-22288: file or LOB operation FILEOPEN failed
No such file or directory

您必须将您的 XML 文件放在数据库服务器上操作系统帐户有权访问的目录中,并创建一个指向服务器上该位置的目录对象;然后引用目录对象名称,而不是底层文件系统路径。

【讨论】:

  • 比我的更好更完整的答案。
【解决方案2】:

错误:ORA-22285:文件打开操作的目录或文件不存在

如果我的 XML 文件存在,我不明白为什么路径 C:\XMLS\ 确实存在。

原因是 XML 文件存在于您的本地硬盘上,但 PL/SQL 运行在数据库服务器上。如果您想通过DBMS_LOB 访问它,您需要将文件放在数据库服务器上。

【讨论】:

  • 你知道如何获取l_loc 变量带来的东西,我如何使用dbms_output 来验证路由是否与它带来的东西正确
【解决方案3】:

尝试以下操作:

  1. 将 DIR_XML 文件夹设为共享文件夹,对所有人具有读/写权限
  2. 使用目录路径“\\192.168.2.100\dir_xml”而不是“C:\DIR_XML”

将 192.168.2.100 替换为 C:\DIR_XML 所在的 IP 地址或机器名

【讨论】:

    【解决方案4】:

    不要使用 c:\ 路径。使用网络路径。确保 \123.3.3.3\xml\ 文件夹可以从您的 sql 客户端计算机以及 Oracle 服务器访问。如果您检查您的 Ora tnsnames.ora 文件,您可以找到您的数据库服务器名称。 检查该服务器创建一个共享文件夹,然后使用它。 192.168.1.0\xml\ tnsnames.ora 示例

    ORA11 =
     (DESCRIPTION = 
       (ADDRESS_LIST =
         (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.0)(PORT = 1521))
       )
     (CONNECT_DATA =
       (SERVICE_NAME = ORA12)
     )
    )
    

    【讨论】:

      猜你喜欢
      • 2012-04-05
      • 2010-09-11
      • 2015-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-14
      • 1970-01-01
      相关资源
      最近更新 更多