Oracle pl/sql 从物理目录中读取文件的内容

Posted

技术标签:

【中文标题】Oracle pl/sql 从物理目录中读取文件的内容【英文标题】:Oracle pl/sql Read the contents of a file from Physical Directory 【发布时间】:2014-02-02 09:56:06 【问题描述】:

我的问题如下: 我正在尝试创建一个将在 sqlplus 中执行的脚本,该脚本将做的是我将有一个文件,您可以在其中写入每行的 1 个名称。所以我想使用一个关联数组,我将在其中逐行读取文件的内容(每行 1 个名称)并将每个名称存储在数组中。

我的问题是我不能使用 UTL_FILE 包,它有一个准备好的 GET_LINE 过程来获取每一行的名称,因为它必须将 Oracle 的“逻辑目录”作为参数。 我的问题是我无法对数据库进行更改,例如创建新目录或使用 in 文件的默认目录之一。我必须找到一个解决方案,我将从物理位置读取文件的内容。 我恳请在 2 个领域提供一些帮助。如果您知道可以在物理位置上工作的任何其他软件包,或者如果知道我可以调用sqlplus(sqlplus用户名/传递@myscript)并将其作为参数提供给那里的任何其他方式,请帮助我 输入文件或比如从那里初始化数组。

提前谢谢你。 任何帮助将不胜感激 乔治

【问题讨论】:

您是在服务器上还是在客户端计算机上运行 SQL*Plus? 【参考方案1】:

显然,最好的解决方案是使用 UTL_FILE 或外部表。因此无法更改数据库是一个主要问题。如果您没有创建目录对象的权限并且无法说服特权用户代表您这样做,那么您的问题基本上就变成了

“如何规避对数据库施加的安全限制?”

嗯,有两种可能。

如果 DBA 不小心启用了 init.ora 文件中的 UTL_FILE_DIR 参数,您仍然可以通过将绝对文件路径传递给 FOPEN() 来使用 UTL_FILE。

或者,您可以编写 Java 存储过程来与操作系统上的文件进行交互。这需要通过 Java 安全模型授予权限。 Find out more。同样,您只会有这个,而不会询问您是否有松散的 DBA。

让我说清楚,这两个“解决方案”都是灰色帽子。您确实应该尝试通过适当的渠道获得必要的特权。如果 DBA 团队不创建目录,您可以使用,您需要将其上报给您的老板。

【讨论】:

获取数据库权限或对其进行任何更改是一个严重的问题。要要求对数据库进行更改,您必须 1000% 确定这不能以任何其他方式完成。我解决它的一种白痴方法是在 in 文件中定义变量。就像 5 个用户一样,我是 DEFINE USER1 = asdasd 并使用 & 将名称作为变量获取,但这是一种非常业余和白痴的方法。下面的一位朋友建议使用 DBMS_LOB 包。我明天会检查一下,如果它有效,那么不需要对 dba 进行权限或更改。非常感谢您的关心 我试过 BFIELNAME(请参阅我对该帖子的评论),它不会为你做。【参考方案2】:

如果您无法对数据库进行任何更改,并且现有数据库无法为您提供所需的权限,那么您就不走运了。

UTL_FILE 要么需要存在 Oracle 目录对象,该对象指向数据库服务器上您拥有权限的物理目录,要么您正在使用通过已弃用的 @987654322 获得访问权限的物理目录@ 范围。您似乎在说这些都不是一个可行的选择。如果是这种情况,则不能使用UTL_FILE

您还可以创建一个可以从文件中读取数据的外部表。这将要求您可以创建 Oracle 目录对象和外部表。同样,听起来您是在说这不是一个选项,因此外部表已退出。

您可以编写一个从文件中读取的 Java(或 .Net,如果您在 Windows 上)存储过程。这将要求您创建该过程并授予所有者必要的文件系统权限。听起来你说这也不是一个选项,所以 Java 存储过程已经出局了。

如果您将文件移动到客户端计算机,您可以使用客户端计算机上的 SQL*Loader 将数据加载到数据库中的表中。但是,这将要求您在数据库中创建一个物理表,这听起来像是您说的不可能。所以 SQL*Loader 出来了。

如果您可以将文件移动到客户端,那么您显然可以使用您想要读取文件的任何语言编写程序并构建您想要的任何 PL/SQL 块。但这不适用于存储在数据库服务器上的文件,除非您的客户端计算机可以在服务器上以某种方式挂载目录的某些非常奇怪的权限授予。

所以我们又回到了开始的地方。从服务器的操作系统读取文件需要能够读取该文件的权限。您似乎在说您没有也无法获得这些特权。因此,你说你不能做你想做的事。组织中要求您实施此更改的任何人都需要与阻止您获得工作所需特权的人交谈。其中之一需要让步。

【讨论】:

下面的 1 条评论表明我可以使用 DBMS_LOB 包。如果这个可以从物理路径而不是目录读取,那么可以在不更改数据库的情况下完成这项工作 @GeorgeGeorgiou - 不。您需要dbms_lob 的目录对象。为什么 Oracle 会费尽心思开发系统来控制对服务器文件系统上文件的访问,并在一个包 (utl_file) 中强制执行,然后在另一个包中创建一个违反该控制系统的后门?那将是荒谬的。

以上是关于Oracle pl/sql 从物理目录中读取文件的内容的主要内容,如果未能解决你的问题,请参考以下文章

从 .txt 文件读取数据并将其插入 Oracle SQL DB [PL/SQL,Unix 脚本]

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

PL/SQL配置和连接远端数据库

PL/SQL32位连接Oracle 11g64位

Oracle 存储过程无法生成 csv 文件 - ORA-06502: PL/SQL: numeric or value error: string buff

尝试从过程中获取数据时:PL/SQL - 数字或值错误