让我们考虑一个 Table STUD 和一个 ROW-Level TRIGGER 是通过 INSERT 查询实现的。我的场景是这样的,每当插入一行时,就会触发一个触发器,它应该访问一些放置在硬盘中的脚本文件,并且最终应该打印结果。那么,这件事可能吗?如果是,那么这个东西应该以动态形式存在,即如果我们改变脚本文件的内容,那么oracle也应该反映这些变化。
我曾尝试使用外部过程为 java 执行此操作,但对我想要的结果不太满意。
请就这种情况以及可以实施的方式提出您的观点。
让我们考虑一个 Table STUD 和一个 ROW-Level TRIGGER 是通过 INSERT 查询实现的。我的场景是这样的,每当插入一行时,就会触发一个触发器,它应该访问一些放置在硬盘中的脚本文件,并且最终应该打印结果。那么,这件事可能吗?如果是,那么这个东西应该以动态形式存在,即如果我们改变脚本文件的内容,那么oracle也应该反映这些变化。
我曾尝试使用外部过程为 java 执行此操作,但对我想要的结果不太满意。
请就这种情况以及可以实施的方式提出您的观点。
一个社区维基,原因是这是一个坏主意。
将文件用于动态代码的原因是愚蠢的。
插入的每一行都必须打开一个文件,读取整个内容,解析它并用结果“做点什么”。这将是缓慢的。
根据操作系统环境,您可能无法同时打开文件进行读写。因此,您可能会发现必须关闭数据库才能将代码更改“提升”到文件中。
根据操作系统环境,您甚至可能会发现一次只能读取一个会话。
也许触发器会在“保存”过程中读取文件并执行部分代码。
文件安全将与数据库安全完全分开,从而造成维护上的麻烦。
简而言之,将动态代码存储在一个表中,而不是一个文件中,将是一个巨大的改进。
无论如何都不应该使用动态代码的原因:
动态代码尚未被解析/编译。所以它可能不起作用,在它执行之前你不会发现。
由于减少了解析开销,静态代码比动态代码执行得更好。
杂项。原因
如果我想访问一个正在执行一些操作系统处理的 sh 文件怎么办?
从数据库内部执行操作系统有三种方式。
外部过程,它们是用 C 或 Java 编写的 OS 库的 PL/SQL 包装器。从 Oracle 8.0 开始可用。 了解更多。
模拟host
命令的 Java 存储过程。这是 Java 的手动包装器Runtime
。此命令将以oracle
OS 用户的强大权限执行,因此请勿将此过程公开用于一般用途。取而代之的是让一个安全的用户拥有它,并编写存储过程来公开特定的操作系统功能(例如要执行的过程,要执行mkdir
的函数ls
)。自 Oracle 8i 以来可能。 了解更多。
DBMS_SCHEDULER。除了后台数据库作业,我们还可以使用计划运行的操作系统作业。从 Oracle 10g 开始可用。 了解更多
在这三个选项中,DBMS_SCHEDULER 可能是最安全的选项。顾名思义,它旨在定时运行程序(如 unix cron
),因此它不适合按需运行(例如通过触发器)。但是,可能不需要触发器就可以满足您的业务逻辑。外部过程不适用于运行 shell 脚本。
外部程序是外部的,需要更多的努力来与数据库组件进行协调。这适用于发布应用程序的新版本和进行备份时。当(比如说)开发环境和实时环境在不同的平台上时,它们也可能很麻烦。
让数据库执行任意代码是一个非常糟糕的主意。在大多数情况下,所需要的只是一种将参数传递给可执行文件的机制。