PL/SQL 不是我的母语。Oracle 支持用 Java 编写存储过程。与在 PL/SQL 中编写存储过程相比,这样做有什么优势
8 回答
在甲骨文世界中,一般的发展顺序应该是:
尽可能纯粹使用 SQL 来完成。如果您需要的不仅仅是 SQL,请使用 PL/SQL。如果您需要一些 PL/SQL 不能做的事情,那么请使用 Java。如果所有其他方法都失败了,请使用 C。如果你不能用 C 来做,请慢慢远离问题......
PL/SQL 存储过程是将业务逻辑移动到任何集成技术都可以访问的层的绝佳方式。包中的业务逻辑(不要编写独立的函数和过程——它们会随着时间的推移以无法管理的方式增长)可以通过 Java、C#、PL/SQL、ODBC 等执行。
PL/SQL 是在纯 SQL 之外处理大量数据的最快方法。“批量绑定”功能意味着它可以很好地与 SQL 引擎配合使用。
Java 存储过程最适合创建与网络或操作系统交互的功能。例如,发送电子邮件、FTP 数据、输出到文本文件并将其压缩、执行主机命令行。
在使用 Oracle 时,我从来不需要编写任何 C 语言,但大概它可以用于与遗留应用程序集成。
只有当你不能在 PL/SQL 中做到这一点时(或者 PL/SQL 被证明太慢,我相信这将是非常罕见的)。
作为一个案例研究......我们在生产中运行了一个 java 存储过程(Oracle 9i),它最初是用 java 编写的,因为当时我们认为 java 很酷,我早就改变了主意。反正。有一天,数据库崩溃了,它重新启动后 java SP 不起作用。在与 oracle 支持反复来回之后,他们并不真正知道问题出在哪里,他们提出的唯一建议涉及很多停机时间。这不是一个选择。30 分钟后,我用 PL/SQL 重写了 java SP。
现在,它运行得更快,是 oracle “本机”,与其他对象共享相同的部署过程,并且更易于调试。
PL/SQL 是一种非常强大的语言。如果您正在编写存储过程,请花时间学习它,而不是仅仅在 java 中做事,因为这就是您所知道的。
主要优点是可以访问 PL/SQL 中没有的 API 和语言功能。例如,我将它们用于正则表达式处理、文件/目录操作和 XML 解析。
有很多缺点:
- 工具支持差
- 缺乏对 JVM 的控制
- DBA 通常没有接受过 Java 培训。为了支持您的生产代码,您要么需要对 DBA 进行更多培训,要么聘请受过 Java 培训的支持人员
将 Java 移至应用程序服务器通常是一种更好的方法,因为这可以抵消这些缺点。有出色的工具支持,对 JVM 的出色控制,并且有大量人员在流行的应用程序服务器上接受过培训,因此很容易找到支持人员。远离数据库的性能损失是有机会成本的,但是让 Java 靠近数据库并不会给您带来很大的性能提升。
您绝对需要一个理由在数据库中使用 Java,而不是 a) PL/SQL 存储过程或 b) 数据库外部的 Java。
Java 使编写与数据库无关的代码成为可能。它允许您重用现有代码并显着提高生产力。
我发现 Java 存储过程有用的一件事是文件 IO。与 Oracle 的 UTL_FILE 包相比,Java 具有更丰富的文件 IO 功能集,允许开发人员删除文件、添加目录等。
优点:
- 可以在客户端和数据库中共享相同的应用程序逻辑
- 访问 Java API。注意每个数据库支持的 java 版本——我相信 10g 只支持 1.4(这意味着在我的工作中我们必须非常小心,因为我们的主要代码库最近已经迁移到 1.5)。
缺点:
- 执行大量数据库访问的 Java 存储过程可能非常慢
- 更难部署你的代码
我使用 Oracle embedded java 解决了两个问题:
1) 执行一个 PLSQL 过程,将查询结果批量存储在文本文件中并通过 FTP 发送。这个文件非常大,我使用 Java 压缩它。
2)在与数据库直接连接的客户端-服务器应用程序中,比较用户发送给应用程序的密码(不是数据库用户密码)用MD5散列,这样密码就不会以明文形式通过网络传播。我不确定这是否是解决此问题的更好解决方案,我现在要问它。:)
当您在 PL/SQL 中绝对无法做到这一点时,或者如果 Java 可以让您获得更高的性能,请使用 Java。
例如,如果您希望在 PL/SQL 程序(日志记录、外部调用等)中使用套接字,您可以:
- 编写一个使用 UTL_TCP 的 PL/SQL 客户端。但是,没有办法仅使用本机 PL/SQL 来执行 UDP。
- 编写一个使用 TCP 或 UDP 套接字的 Java 客户端。
在第一种情况下,如果远程服务出现问题,您有一个同步套接字可以备份您的 PL/SQL 调用。此外,如果您使用 dbms_session.reset_package(如在 OWA 中),则必须为每个请求重新连接套接字,这非常昂贵。
在第二种情况下,TCP 仍然是同步的,但如果您需要异步、非阻塞行为,您可以使用 UDP。此外,reset_package 不会重置 Java TCP 或 UDP 套接字,因此您无需处理拆卸/重新连接的痛苦。
答案是从不。如果您需要编写程序来加载或处理数据,则需要在网络上的另一台计算机的数据层之外进行。
直接在您的数据层上运行外部应用程序,或者上帝禁止在您的数据层的进程内运行,或者当本机查询语言更适合手头的工作时错误应用外部语言对于小规模的内部定制是完全可以接受的应用。他们在那个舞台之外根本没有立足之地。