如何从 pl sql 过程运行 sql 脚本

Posted

技术标签:

【中文标题】如何从 pl sql 过程运行 sql 脚本【英文标题】:How to run sql scripts from a pl sql procedure 【发布时间】:2011-01-23 05:35:54 【问题描述】:

我有一个类似的程序:

CREATE OR REPLACE PROCEDURE test is 
BEGIN

  DBMS_OUTPUT.PUT_LINE('This is a Test');
END;

我想运行一些存储在当前目录中的 sql 脚本。 我可以使用 '@scriptname.sql' 从 sqlplus 运行它们,但我怎样才能从程序内部进行呢?例如:

CREATE OR REPLACE PROCEDURE test is 
BEGIN

  DBMS_OUTPUT.PUT_LINE('This is a Test');
  @scriptname.sql

END;

这似乎不起作用!是否有特定的从 pl/sql 程序运行 sql 脚本?

【问题讨论】:

对我来说,为什么要将脚本引用包含在存储过程(或匿名,就此而言)中是否有意义——不要介意脚本位置的问题。您可以使用 SQLPlus 从单个主脚本运行脚本,而无需存储过程。 我猜这是对 OP 实际需求的粗略简化... 【参考方案1】:

一般来说,你不能,因为 pl/sql 在数据库中运行,在服务器上,而 sqlplus 是一个客户端进程。服务器甚至不能依赖与客户端及其文件在同一系统上,更不用说知道如何找到客户端所引用的文件了。即使语法受支持(但不支持),您的 sql 脚本也必须位于服务器上,位于服务器知道并可以访问的位置。

【讨论】:

【参考方案2】:

实际上,您可以在 SQL*Plus 中执行此操作 - 您只需确保 @ 是该行的第一个字符,例如:

CREATE OR REPLACE PROCEDURE test is 
BEGIN

    DBMS_OUTPUT.PUT_LINE('This is a Test');
@scriptname.sql

END;

SQL*Plus 将读取脚本的全部内容并将其插入过程中的该点,然后按照给定的过程创建过程。这意味着您不能在scriptname.sql 中使用 SQL*Plus 命令。此外,在数据库上创建的实际过程中不会有任何对@scriptname.sql 的引用。

【讨论】:

【参考方案3】:

您可以执行操作系统命令来启动 SQLPlus 并让它执行脚本。您可以在启动时将文件名传递给 SQLplus,它会执行它。

Google 外部程序和 extproc 或 this article。或者类似call OS command with Java

【讨论】:

而且它仍然在服务器上运行,而不是在客户端上。 实际上在服务器或其他地方运行只是必须编码的细节之一。我当然不是说这很容易,但如果有可能在服务器上执行代码并使其在其他地方执行。会有一堆防火墙、RPC(或类似)问题等需要解决,但这是可能的。这不是我认为有什么好处的事情,但我不知道请求者的情况。【参考方案4】:

您可以编写Java Stored Procedure 来打开文件并将其内容作为字符串返回,然后在字符串上调用Execute Immediate。

要非常小心,因为这些文件中的任何恶意 sql 都可以为所欲为。

【讨论】:

如果 SQL 文件包含 SELECT 语句(选择的数据应该去哪里?立即执行不会在屏幕上显示它。)或 SQLplus 语句,如 EXEC、SET ESC 等,这将不起作用. 此外,您可能需要逐条阅读和执行它,这也不容易。【参考方案5】:

即使应该有解决方案,我也不建议这样做。 PL/SQL 过程基本上是一个 SQL 脚本。任何一个 1. 从数据库外部运行您的 SQL 脚本,例如通过 shell 脚本或 2. 在你的过程中移动 SQL 代码。

【讨论】:

以上是关于如何从 pl sql 过程运行 sql 脚本的主要内容,如果未能解决你的问题,请参考以下文章

从 shell 脚本调用 PL/SQL 存储过程并捕获 out 参数

PL/SQL 编译失败时如何让 SQL*Plus 退出

重新运行 PL/SQL 脚本命令

运行 pl/sql 脚本时遇到问题

将 PL/SQL ETL 流程翻译成 HiveQL

PL/SQL 过程未返回预期结果