使用 PL/SQL 将数据从 file.txt 导入 Oracle SQL 表

Posted

技术标签:

【中文标题】使用 PL/SQL 将数据从 file.txt 导入 Oracle SQL 表【英文标题】:Import data from file.txt to table Oracle SQL using PL/SQL 【发布时间】:2020-03-05 15:46:14 【问题描述】:

我正在尝试从 c:\Dir 读取 txt 类型的文件并将内容插入到 Oracle Sql 表中

set SERVEROUTPUT ON
CREATE OR REPLACE DIRECTORY MYDIR AS ' C:\dir';

DECLARE
  vInHandle  utl_file.file_type;
  eNoFile    exception;
  PRAGMA exception_init(eNoFile, -29283);
BEGIN
  BEGIN
    vInHandle := utl_file.Fopen('MYDIR','attachment.txt','R');
    dbms_output.put_line('The File exists');
  EXCEPTION
    WHEN eNoFile THEN
      dbms_output.put_line('The File not  exists');
  END;
END fopen;
/

我的文件不存在,但我有这个文件

【问题讨论】:

你的Oracle数据库能看到你的C盘吗? 对不起,我不明白 C 盘是什么意思 您要读取的文件位于C:\dir。我假设这是您个人计算机上的位置,对吗? Oracle 数据库是否也托管在您的个人计算机上?如果没有,它就无法访问该文件。 @JoshEller 这不一定是真的;只要数据库服务器可以使用必要的权限,通过挂载/映射来查看目录。是否值得在数据库服务器上安装特定的 c:\ 驱动器完全是另一回事! @Boneist 公平点,我只是假设这里不太可能是这种情况 【参考方案1】:

我不知道您在发布的第一条语句中目录名称前面的空格是否有所不同(或者只是一个错字),但是 - 尽管如此,这就是通常的做法。

在硬盘上创建目录:

C:\>mkdir c:\dir

SYS 身份连接到数据库(因为它拥有数据库以及目录);创建目录(Oracle 对象)并向将使用该目录的用户授予权限:

C:\>sqlplus sys as sysdba

SQL*Plus: Release 11.2.0.2.0 Production on ╚et O×u 5 18:34:43 2020

Copyright (c) 1982, 2014, Oracle.  All rights reserved.

Enter password:

Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production

SQL> create or replace directory mydir as 'c:\dir';

Directory created.

SQL> grant read, write on directory mydir to scott;

Grant succeeded.

SQL>

你不需要这个,因为你已经有了文件;我将通过假脱机表格内容来创建它。

SQL> connect scott/tiger
Connected.
SQL> spool c:\dir\example.txt
SQL> select * From dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

SQL> spool off;
SQL> $dir c:\dir\*.txt
 Volume in drive C is OSDisk
 Volume Serial Number is 7635-F892

 Directory of c:\dir

05.03.2020.  18:39               539 example.txt
               1 File(s)            539 bytes
               0 Dir(s)  290.598.363.136 bytes free

SQL>

最后,重用你写的代码:

SQL> set serveroutput on
SQL>
SQL> DECLARE
  2    vInHandle  utl_file.file_type;
  3    eNoFile    exception;
  4    PRAGMA exception_init(eNoFile, -29283);
  5  BEGIN
  6    BEGIN
  7      vInHandle := utl_file.Fopen('MYDIR','example.txt','R');
  8      dbms_output.put_line('The File exists');
  9    EXCEPTION
 10      WHEN eNoFile THEN
 11        dbms_output.put_line('The File not  exists');
 12    END;
 13  END fopen;
 14  /
The File exists

PL/SQL procedure successfully completed.

SQL>

工作正常(恭喜,您编写的代码确实有效!)。


那么,你做错了什么?

正如我所说,c:\dir 前面的空格:CREATE OR REPLACE DIRECTORY MYDIR AS ' C:\dir'; 数据库不在您的计算机上,而是在单独的数据库服务器上 表示你可能创建了目录,但它指向的是数据库服务器上的c:\dir目录,而不是你自己的PC!

正如 Boneist 所评论的,可以在不是数据库服务器的计算机上创建一个目录(Oracle 对象),但这不是我们通常做的事情。如果您选择此选项,则必须在创建目录时使用 UNC(通用命名约定)。


您可能要考虑的另一个选项是使用 SQL Loader。它是一个操作系统实用程序,与数据库或(完整的,非即时的)客户端软件一起安装。它的优点是它可以在您的本地 PC 上运行(即您不必访问数据库服务器)并且速度非常快。您将创建一个控制文件,告诉 Oracle 如何加载存储在源 (.txt) 文件中的数据。

另一个在后台使用 SQL 加载器的选项是使用外部表。它是另一个 Oracle 对象,它指向源 (.txt) 文件,并允许您使用简单的 SQL SELECT 语句访问它。可能的缺点:它仍然需要访问 Oracle 目录(就像您的 UTL_FILE 选项一样)。

【讨论】:

以上是关于使用 PL/SQL 将数据从 file.txt 导入 Oracle SQL 表的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 PL SQL 函数从 xmltype 数据生成 xml 报告

PL/SQL 仅使用游标将 2 个表中的数据检索到新表中

将数据集合从 .NET 传递给 PL/SQL 包过程或函数?

如何使用 pl/sql 中的游标将多列数据插入包含单列的表中?

如何使用 pl sql 过程从结构仅在运行时知道的 oracle 表中动态获取数据?

避免在 PL/SQL 中从双重联合中选择