如何在调用脚本中通过正则表达式执行 sql 脚本?

Posted

技术标签:

【中文标题】如何在调用脚本中通过正则表达式执行 sql 脚本?【英文标题】:How to execute sql scripts via regex in calling script? 【发布时间】:2016-06-23 21:52:42 【问题描述】:

我有一个带有一些 pl/sql 代码的 sqlplus 脚本,它调用一些罐装的 oracle 12c 程序来进行分区维护——这些程序在一个目录中生成一系列 sql 文件——每个文件只是一系列的 alter table drop分区语句。目标是然后执行那些生成的 sql 脚本。生成的 sql 文件都有不同的命名,但都有一个共同的命名模式:SOA_SYS*​​.sql

根据我的研究,尝试从实际的 plsql 代码中调用这些 sql 脚本似乎不可行或不可取。如果是这样的话,我似乎有 3 个选择:

从 sqlplus 脚本中调用 sql 脚本。是否可以使用 sqlplus 脚本语言来做到这一点并使用正则表达式来获取对所有文件的引用,然后遍历它们并使用 @file.sql 执行每个文件?还是sqlplus在这方面太局限了?

创建一个运行 sql 文件的 dbms_scheduler 作业,并安排它确保文件生成的时间。 dbms_scheduler作业中是否可以动态调用多个sql脚本?

在服务器上创建一个 cron 作业,该作业执行一个 shell 脚本,该脚本遍历目录中的 sql 文件并打开 sqlplus 以连接到每个数据库并通过 @file.sql 调用它。

还有其他选择吗?实现预期目标的推荐和最简单的方法是什么?谢谢。

【问题讨论】:

是否有必要创建脚本 - 是否可以动态运行您放入其中的命令?如果做不到这一点,您能否创建一个主脚本来调用其他脚本,而不需要一个列表或正则表达式? 【参考方案1】:

会有很多步骤,但应该可以在 PL/SQL 中执行此操作。它可以让您更好地控制如何运行运行语句,但这将是很多工作。

这些步骤可能是这样的:

    查找动态文件。 将每个文件加载到 CLOB 中。 将 CLOB 拆分为多个 SQL 语句并对其进行迭代。 对语句进行分类,以确保每个语句都是预期的ALTER 语句。 删除语句终止符,可能是;/。 (这些终止符在动态 SQL 中不起作用。) 使用execute immediate 运行语句。 报告状态,包括错误消息或成功的反馈消息,如“表已更改”。也许将结果存储在某个地方的日志中。

第 1 步可以通过外部表预处理器 shell 脚本来实现,如this article 中的示例所述。第 2 步可能相当简单,只需致电 DBMS_XSLPROCESSOR.READ2CLOB。

步骤 #3 到 #7 可能非常复杂,具体取决于 SQL 语句的复杂性。除非 SQL 语句非常统一,否则正则表达式将不足以处理它。但我的开源项目plsql_lexer 可以处理复杂 SQL 语句的这些步骤。即使进行了解析,您仍然需要查看大约 100 行代码来处理结果。有关实际示例,请参阅项目自述文件。


但是控制固定程序并让它们运行语句而不是将它们写入文件会更容易。或者至少将它们存储在表格中。我认为这是一些第 3 方工具?如果是这样,可能有一些方法可以破解它以更好地工作。

如果幸运的话,它是一个可以修改的 PL/SQL 程序。他们把它包起来了吗?别担心,网上有很多解包器。

如果它正在运行 PL/SQL,但您无权访问它,您仍然可以控制它。例如,它可能使用UTL_FILE 来写入文件。但我敢打赌,他们并没有完全用SYS.UTL_FILE 来限定它。在这种情况下,您可以创建自己的UTL_FILE 版本,将数据写入表而不是文件系统。然后在应用程序架构上安装包,它将使用新包。

【讨论】:

以上是关于如何在调用脚本中通过正则表达式执行 sql 脚本?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 LINUX 中通过 CRONTAB 调度脚本 [重复]

使用java中的jsch在linux中通过sudo命令执行shell脚本以启动服务

如何在项目中通过LINK标签链接自己javascript脚本?

如何在 shell 脚本中使用正则表达式?

从 bash 脚本中通过 ssh 在远程主机上执行命令

如何在python中通过正则表达式获取dict值