服务器端编程:PL/SQL、Java 和 JavaScript
SQL 介绍了结构化查询语言 (SQL) 语言以及数据库如何处理 SQL 语句。本章介绍存储在数据库中的过程语言/SQL (Procedural Language/SQL,PL/SQL) 或 Java 程序如何使用 SQL。
-
服务器端编程简介在 SQL 等非过程语言中,指定要对其操作的数据集,但不指定要执行的操作或执行这些操作的方式。
-
PL/SQL 概述 PL/SQL 提供了一种易于使用、与 SQL 无缝、强大、可移植且安全的服务器端存储过程语言。可以使用称为 PL/SQL 单元的过程对象访问和处理数据库数据。
-
Java in Oracle AI Database 概述 Java 已成为首选的面向对象的编程语言。
-
Oracle AI Database 中的 JavaScript 概述 JavaScript 是当今最受欢迎的编程语言之一。在 Linux x86-64 或 Linux aarch64 上部署的 Oracle AI Database 将 JavaScript 添加到服务器端开发支持的语言列表中。
-
触发器概览 数据库触发器是使用 PL/SQL、Java 或 JavaScript 编写的已编译存储程序单元,在某些情况下 Oracle Database 会自动调用这些程序单元(“触发”)。另请参阅:SQL 以了解 SQL 语言的概述。
服务器端编程简介
在 SQL 等非过程语言中,指定要操作的数据集,但不指定要执行的操作或要执行的数据集的方式。
在过程语言程序中,大多数语句执行依赖于以前或后续语句以及 SQL 中不可用的控制结构(如循环或条件分支)。有关过程语言与非过程语言之间差异的图示,假设以下 SQL 语句查询 employees 表:
SELECT employee_id, department_id, last_name, salary FROM employees;
上述语句请求数据,但不对数据应用逻辑。但是,假设您希望应用程序根据薪金和部门绩效来确定数据集中的每个员工是否应该获得加薪。加薪的一个必要条件是,该雇员在过去五年中没有收到超过三次加薪。如果需要加薪,则应用程序必须调整薪金并向经理发送电子邮件;否则,应用程序必须更新报表。
问题在于需要条件逻辑和程序流控制的过程性数据库应用程序如何使用 SQL。基本发展办法如下:
-
使用客户端编程将 SQL 语句嵌入以过程语言(例如 C、C++ 或 Java)编写的应用程序
可以在源代码中放置 SQL 语句,并在编译之前将其提交给 precompiler 或 Java 转换器。或者,您可以消除预编译步骤,并使用 API(如 Java 数据库连接 (JDBC) 或 Oracle Call Interface (OCI))来使应用程序能够与数据库交互。
-
使用服务器端编程开发驻留在数据库中的数据逻辑
应用程序可以显式调用以 PL/SQL(发音为 P L sequel )或 Java 编写的存储子程序(过程和函数)或 JavaScript。您还可以创建 trigger ,该触发器是命名的程序单元,存储在数据库中,并针对指定的事件进行调用。
本章介绍了第二种方法。服务器端编程的主要好处是,数据库内置的功能可以部署在任何地方。数据库(而不是应用程序)确定在给定操作系统上执行任务的最佳方式。此外,子程序还可以通过集中处理服务器上的应用程序来提高可扩展性,从而使客户机能够重用代码。由于子程序调用既快速又高效,因此单个调用可以启动计算密集型存储子程序,从而减少网络流量。
您可以使用以下语言在 Oracle AI Database 中存储数据逻辑:
-
PL/SQL
PL/SQL 是 SQL 的 Oracle AI Database 过程性扩展。PL/SQL 与数据库集成,支持所有 Oracle SQL 语句、函数和数据类型。在数据库 API 中编写的应用程序可以调用 PL/SQL 存储的子程序并将 PL/SQL 代码块发送到数据库以供执行。
-
Java
Oracle AI Database 还支持开发、存储和部署 Java 应用。Java 存储子程序在数据库中运行,并且与中间层运行的程序无关。使用与 PL/SQL 相似的执行模型的 Java 存储子程序与 SQL 的接口。
-
JavaScript
在 Linux x86-64 或 Linux aarch64 上部署时,Oracle AI Database 允许开发人员在 JavaScript 中表达业务逻辑。DBMS_MLE PL/SQL 程序包及其子例程可以临时执行 JavaScript。通过将业务逻辑存储为 JavaScript 方案对象,您可以编写更复杂的应用程序。调用规范以与 Java 存储过程类似的方式公开存储在 SQL 和 PL/SQL 中数据库的 JavaScript 代码。
另请参见:
-
Oracle AI Database Development Guide,了解如何使用预编译器和 API 嵌入 SQL
-
Oracle AI Database 快速入门 Oracle AI Database 开发,了解 Oracle AI Database 应用开发
-
Oracle AI Database Development Guide,了解如何选择编程环境
-
Oracle AI Database JavaScript Developer’s Guide,详细了解 Oracle AI Database 中的 JavaScript 支持。
PL/SQL 概览
PL/SQL 提供了一种服务器端的存储过程语言,易于使用,与 SQL 无缝连接,功能强大,可移植且安全。可以使用称为 PL/SQL 单元的过程对象访问和处理数据库数据。
PL/SQL 单元通常按以下方式分类:
-
PL/SQL 子程序是存储在数据库中的 PL/SQL 块,可以按名称从应用程序调用。创建子程序时,数据库将对该子程序进行语法分析,并将其解析后的表示形式存储在数据库中。可以将子程序声明为过程或函数。
-
PL/SQL 匿名块是应用程序中显示的 PL/SQL 块,不会在数据库中命名或存储。在许多应用程序中,PL/SQL 块可以出现在可以显示 SQL 语句的任何位置。
PL/SQL 编译器和解释器嵌入在 Oracle SQL Developer 中,使开发人员能够在客户端和服务器上使用一致的开发模型。此外,还可以从多个数据库客户机(例如 Pro*C、JDBC、ODBC 或 OCI)以及从 Oracle Reports 和 Oracle Forms 调用 PL/SQL 存储过程。
-
PL/SQL 子程序 PL/SQL 子程序是一个命名的 PL/SQL 块,通过该块,调用方可以提供仅可输入、仅输出或输入和输出值的参数。
-
PL/SQL 程序包 PL/SQL 程序包是存储在数据库中的一组相关子程序以及它们使用的显化游标和变量,供以后作为一个单位使用。打包的子程序可由应用程序或用户显式调用。
-
PL/SQL 匿名块 PL/SQL 匿名块是未命名的非持久性 PL/SQL 单元。
-
PL/SQL 语言结构 PL/SQL 块可以包含各种不同的 PL/SQL 语言结构。
-
PL/SQL 集合和记录许多编程技术使用集合类型,例如数组、包、列表、嵌套表、集合和树。
-
PL/SQL 运行方式 PL/SQL 支持解释执行和本机执行。
另请参见:
-
Oracle AI Database PL/SQL Language Reference(了解有关 PL/SQL 程序包的完整信息)
PL/SQL 子方案
PL/SQL 子程序是一个命名的 PL/SQL 块,通过该块,调用方可以提供仅可输入、仅输出或输入和输出值的参数。
子程序可解决特定问题或执行相关任务,并充当模块化、可维护的数据库应用程序的构建块。子程序是 PL/SQL 过程或 PL/SQL 函数。过程与函数仅有一处不同:函数始终向调用方返回一个值,而过程则并非如此。本章中的术语 PL/SQL 过程是指过程或函数。
-
PL/SQL 子程序的优点:与客户端编程相比,服务器端编程具有许多优势。
-
创建 PL/SQL 子程序 独立的存储子程序是在方案级别使用
CREATE PROCEDURE或CREATE FUNCTION语句创建的子程序。在程序包中定义的子程序称为程序包子程序,并被视为程序包的一部分。 -
执行 PL/SQL 子程序 用户可以通过多种方式以交互方式执行子程序。
另请参见:
PL/SQL 子程序的优点
与客户端编程相比,服务器端编程具有许多优势。
优点包括:
-
性能提高
-
与发出单个 SQL 语句或将整个 PL/SQL 块的文本发送到 Oracle AI Database 相比,应用程序必须通过网络发送的信息量很小,因为该信息仅在使用时被调用一次,然后被调用。
-
过程的编译形式在数据库中随时可用,因此在执行时不需要进行编译。
-
如果 SGA 的 shared pool 中存在该过程,则数据库无需从磁盘中检索该过程,可以立即开始执行。
-
-
内存分配
由于存储过程利用了 Oracle AI Database 的共享内存功能,因此它只能将过程的单个副本加载到内存中,以便多个用户执行。在用户之间共享代码可大幅降低对应用程序的数据库内存要求。
-
工作效率提升
存储过程可提高开发效率。通过围绕一组常见过程设计应用程序,可以避免冗余编码。例如,可以编写过程来处理
employees表中的行。任何应用程序都可以调用这些过程,而无需重新编写 SQL 语句。如果数据管理方法发生更改,则只能修改过程,而不能修改使用该过程的应用程序。存储过程也许是实现代码重用的最佳方式。由于任何以任何语言编写的客户端应用程序都可以调用存储过程,因此它们在所有环境中提供最大的代码重用。
-
完整性
存储过程可提高应用程序的完整性和一致性。通过围绕一组常见过程开发应用程序,可以降低编码错误的可能性。
例如,可以测试子程序以保证其返回准确的结果,并在验证后在任意数量的应用程序中重用该子程序而无需重新测试。如果过程引用的数据结构已更改,则只能重新编译该过程。调用该过程的应用程序不一定需要修改。
-
具有定义者权利程序的安全性
存储过程有助于强制实施数据安全性。definer 的权限 PL/SQL 过程与其所有者的 privilege (而不是其当前用户)一起执行。因此,您可以通过仅允许用户通过具有定义者权限的过程和函数访问数据来限制用户执行的数据库任务。
例如,可以授予用户对更新表的过程的访问权限,但不能授予用户对表本身的访问权限。当用户调用该过程时,它将以其所有者的权限运行。仅有权运行该过程(但无权从基础表中查询、更新或删除)的用户可以调用该过程,但不能以任何其他方式处理表数据。
-
使用调用者的权限过程继承特权和方案上下文
invoker 的权限 PL/SQL 过程在当前用户的方案中执行,并具有当前用户的权限。换句话说,调用者的权限过程不与特定用户或方案关联。调用者的权限过程使应用程序开发人员可以轻松地集中应用程序逻辑,即使底层数据在用户方案之间划分也是如此。
例如,对
hr.employees表运行更新过程的hr_manager用户可以更新薪金,而运行相同过程的hr_clerk仅限于更新地址数据。
另请参见:
-
Oracle AI Database PL/SQL Language Reference(了解 PL/SQL 子程序的概述)
-
Oracle AI Database Security Guide,详细了解定义者和调用者的权限
创建 PL/SQL 子程序
独立存储子程序是在方案级别使用 CREATE PROCEDURE 或 CREATE FUNCTION 语句创建的子程序。在程序包中定义的子程序称为程序包子程序,并被视为程序包的一部分。
数据库将子程序作为方案对象存储在数据字典中。子程序有一个规范(包括对任何参数的说明)和一个主体。
示例 11-1 PL/SQL 过程
此示例显示了独立 PL/SQL 过程 hire_employees 的创建语句的一部分。该过程将向 employees 表中插入一行。
CREATE PROCEDURE hire_employees
(p_last_name VARCHAR2, p_job_id VARCHAR2, p_manager_id NUMBER,
p_hire_date DATE, p_salary NUMBER, p_commission_pct NUMBER,
p_department_id NUMBER)
IS
BEGIN
.
.
.
INSERT INTO employees (employee_id, last_name, job_id, manager_id, hire_date,
salary, commission_pct, department_id)
VALUES (emp_sequence.NEXTVAL, p_last_name, p_job_id, p_manager_id,
p_hire_date, p_salary, p_commission_pct, p_department_id);
.
.
.
END;
另请参见:
-
Oracle AI Database PL/SQL Language Reference(了解
CREATE PROCEDURE语句)
执行 PL/SQL 子程序
用户可以通过多种方式以交互方式执行子程序。
这些选项是:
-
使用 Oracle 工具,例如 SQL*Plus 或 SQL Developer
-
在数据库应用程序的代码(例如 Oracle Forms 或预编译器应用程序)中显式调用
-
在其他过程或触发器的代码中显式调用该过程
下图显示了调用 hire_employees 的不同数据库应用程序。
图 1:存储过程的多次执行

或者,特权用户可以使用 Oracle Enterprise Manager 或 SQL*Plus 来使用如下语句运行 hire_employees 过程:
EXECUTE hire_employees ('TSMITH', 'CLERK', 1037, SYSDATE, 500, NULL, 20);
上面的语句在 employees 表中为 TSMITH 插入新记录。
存储过程取决于其主体中引用的对象。数据库会自动跟踪和管理这些依赖项。例如,如果以影响此过程的方式更改 hire_employees 过程引用的 employees 表的定义,则必须重新编译该过程以验证其是否仍按设计工作。通常,数据库会自动管理此类依赖项管理。
另请参见:
-
Oracle AI Database 入门 Oracle AI Database 开发,详细了解 SQL*Plus 和 SQL Developer
-
Oracle AI Database Development Guide,了解有关预编译器的更多信息
-
Oracle AI Database PL/SQL Language Reference(了解如何使用 PL/SQL 子程序)
-
SQL*Plus 用户指南和参考以了解
EXECUTE命令
PL/SQL 程序包
PL/SQL 程序包是一组相关子程序以及它们使用的游标和变量,一起存储在数据库中作为一个单元继续使用。打包的子程序可由应用程序或用户显式调用。
Oracle AI Database 包含许多提供的程序包,这些程序包扩展了数据库功能并提供对 SQL 功能的 PL/SQL 访问权限。例如,UTL_HTTP 程序包允许来自 PL/SQL 和 SQL 的 HTTP 标注访问 Internet 上的数据或调用 Oracle Web Server 磁带。您可以在创建应用程序时使用提供的程序包,也可以在创建自己的存储过程时将程序包用作创意来源。
-
PL/SQL 程序包的优点 PL/SQL 程序包为应用程序开发人员提供了许多优势。
-
创建 PL/SQL 程序包 您可以分两部分创建程序包:规范和主体。软件包规范声明了软件包的所有公共构造,而软件包主体定义了软件包的所有构造(public 和 private)。
-
执行 PL/SQL 程序包子程序 数据库触发器、存储子程序、3GL 应用程序和 Oracle 工具可以引用程序包内容。
PL/SQL 程序包的优点
PL/SQL 程序包为应用程序开发人员提供了许多优势。
优点包括:
-
封装
使用程序包,可以将存储过程、变量、数据类型等封装或分组到指定的存储单元中。封装在开发过程中提供了更好的组织,也提供了更大的灵活性。您无需实际创建程序包主体即可创建规范和引用公共过程。封装可简化权限管理。授予程序包的权限使被授权者可以访问程序包构造。
-
数据安全性
通过程序包定义的方法,可以指定哪些变量、游标和过程是公共的,哪些是私有的。Public 意味着程序包的用户可以直接访问它。Private 意味着它对软件包的用户隐藏。
例如,一个程序包可以包含 10 个过程。您可以定义软件包,以便只有三个过程是公共的,因此可供软件包的用户执行。其余过程是专用的,只能由程序包中的过程访问。不要将公共和专用程序包变量与对
PUBLIC的授权混淆。 -
更好的性能
首次调用程序包中的过程时,整个程序包以小块形式加载到内存中。此加载在一个操作中完成,而不是独立过程所需的单独加载。发生对相关打包过程的调用时,无需执行磁盘 I/O 便可在内存中运行编译的代码。
可以在不影响规范的情况下更换和重新编译软件包主体。因此,引用程序包结构(始终通过规范)的方案对象不需要重新编译,除非还替换了程序包规范。通过使用软件包,可以最大限度地减少不必要的重新编译,从而减少对整体数据库性能的影响。
创建 PL/SQL 程序包
您可以将程序包分为两个部分:规范和主体。软件包规范声明了软件包的所有公共构造,而软件包主体定义了软件包的所有构造(public 和 private)。
以下示例显示了为 employees_management 创建程序包规范的语句的一部分,该语句封装了用于管理员工数据库的多个子程序。程序包的每个部分都是使用不同的语句创建的。
CREATE PACKAGE employees_management AS
FUNCTION hire_employees (last_name VARCHAR2, job_id VARCHAR2, manager_id NUMBER,
salary NUMBER, commission_pct NUMBER, department_id NUMBER) RETURN NUMBER;
PROCEDURE fire_employees(employee_id NUMBER);
PROCEDURE salary_raise(employee_id NUMBER, salary_incr NUMBER);
.
.
.
no_sal EXCEPTION;
END employees_management;
该规范声明了函数 hire_employees、过程 fire_employees 和 salary_raise 以及例外 no_sal。所有这些公共程序对象都可供有权访问该程序包的用户使用。
CREATE PACKAGE BODY 语句定义规范中声明的对象。程序包主体必须在与程序包相同的方案中创建。创建程序包后,您可以开发调用这些公共过程或函数中的任意一个或引发程序包的任何公共异常的应用程序。
另请参阅:Oracle AI Database PL/SQL Language Reference 以了解 CREATE PACKAGE 语句
执行 PL/SQL 程序包子程序
数据库触发器、存储的子程序、3GL 应用程序和 Oracle 工具可以引用程序包内容。
下图显示了调用 employees_management 程序包中的过程和函数的数据库应用程序。
图 2:调用 PL/SQL 程序包中的子程序

数据库应用程序根据需要显式调用打包的过程。在被授予 employees_management 软件包的特权之后,用户可以显式运行其中包含的任何过程。例如,SQL*Plus 可以发出以下语句来运行 hire_employees 程序包过程:
EXECUTE employees_management.hire_employees ('TSMITH', 'CLERK', 1037, SYSDATE, 500, NULL, 20);
另请参见:
-
Oracle AI Database PL/SQL Language Reference(了解 PL/SQL 程序包简介)
-
Oracle AI Database Development Guide,了解如何对 PL/SQL 程序包进行编码
PL/SQL 匿名区块
PL/SQL 匿名块是未命名的非持久性 PL/SQL 单元。
匿名块的典型用途包括:
-
启动对子程序和程序包构造的调用
-
隔离异常处理
-
通过在其他 PL/SQL 块中嵌套代码来管理控制
匿名块不具备所存储子程序的代码重用优势。表 11-1 汇总了两种类型的 PL/SQL 单元之间的差异。
表 1 匿名块和子程序之间的差异
| PL/SQL 单元是否… | 匿名区块 | 子程序 |
|---|---|---|
| 是否使用名称指定? | 否 | 是 |
| 通过每次重复使用进行编译? | 否 | 否 |
| 是否存储在数据库中? | 否 | 是 |
| 是否可由其他应用程序调用? | 否 | 是 |
| 是否可以返回绑定变量值? | 是 | 是 |
| 是否可以返回函数值? | 否 | 是 |
| 是否能够接受参数? | 否 | 是 |
匿名块由可选的声明部分、可执行部分和一个或多个可选的异常错误处理程序组成。以下示例匿名块在变量中选择员工姓氏并输出姓名:
DECLARE
v_lname VARCHAR2(25);
BEGIN
SELECT last_name
INTO v_lname
FROM employees
WHERE employee_id = 101;
DBMS_OUTPUT.PUT_LINE('Employee last name is '||v_lname);
END;
Oracle AI Database 编译 PL/SQL 块并将其放置在 SGA 的共享池中,但不会将源代码或编译后的版本存储在数据库中,以便在当前实例之外重用。与触发器不同,每次将匿名块加载到内存中时都会对其进行编译。共享 SQL 允许重用和共享共享共享池中的匿名 PL/SQL 块,直到它们从共享池中清除为止。
另请参阅:Oracle AI Database Development Guide 以了解有关匿名 PL/SQL 块的更多信息
PL/SQL 语言结构
PL/SQL 块可以包含各种不同的 PL/SQL 语言结构。
这些结构包括:
-
变量和常量
可以在过程、函数或程序包中声明这些构造。可以在 SQL 或 PL/SQL 语句中使用变量或常量在需要时捕获或提供值。
-
游标
您可以在过程、函数或程序包中显式声明 cursor ,以便于以记录为导向的 Oracle AI Database 数据处理。PL/SQL 引擎还可以隐式声明游标。
-
例外
通过 PL/SQL,可以显式处理在处理 PL/SQL 代码期间出现的内部和用户定义的错误条件(称为例外)。
PL/SQL 可以运行 dynamic SQL 语句,这些语句的完整文本在运行时才已知。动态 SQL 语句存储在运行时输入程序或由程序构建的字符串中。此技术使您能够创建通用过程。例如,可以创建一个对表进行操作的过程,该表的名称在运行时才未知。
另请参见:
-
Oracle AI Database PL/SQL Packages and Types Reference(了解有关动态 SQL 的详细信息)
-
Oracle AI Database PL/SQL Packages and Types Reference,了解如何在
DBMS_SQL程序包中使用动态 SQL
PL/SQL 集合和记录
许多编程技术使用集合类型,如数组、包、列表、嵌套表、集和树。
为了支持数据库应用程序中的收集技术,PL/SQL 提供了 TABLE 和 VARRAY 数据类型。通过这些类型,可以声明关联数组、嵌套表和可变大小数组。
-
集合 PL/SQL 集合是一组有序的元素,它们都属于同一类型。
-
Records(记录)是一种 PL/SQL 记录复合变量,它可以存储不同类型的数据值,类似于 C、C++ 或 Java 中的结构类型。记录非常适用于存储表行中的数据或表行中的某些列。
收帐
PL/SQL 集合是一组有序的元素,它们都属于同一类型。
每个元素都具有唯一的下标,用于确定其在集合中的位置。要创建集合,请先定义集合类型,然后声明该类型的变量。
集合的工作方式与大多数第三代编程语言中的数组相同。此外,集合可以作为参数传递。因此,您可以使用这些列将数据移入和移出数据库表,也可以在客户端应用程序与存储的子程序之间移动。
记录
PL/SQL 记录是一种复合变量,它可以存储不同类型的数据值,类似于 C、C++ 或 Java 中的结构类型。记录非常适用于存储表行中的数据或表行中的某些列。
假设您有雇员的相关数据,如姓名、薪金和聘用日期。这些项目在类型上是不同的,但在逻辑上是相关的。通过包含每个货品字段的记录,可以将数据视为逻辑单元。
可以使用 %ROWTYPE 属性声明表示从光标中提取的表行或行的记录。通过用户定义的记录,您可以声明自己的字段。
另请参阅:Oracle AI Database PL/SQL Language Reference 以了解如何使用 PL/SQL 记录
PL/SQL 的运行方式
PL/SQL 支持解释执行和本机执行。
在解释式执行中,PL/SQL 源代码被编译成所谓的字节码表示。作为 Oracle AI Database 的一部分实施的可移植虚拟计算机运行此字节码。
本机执行可为计算密集型单元提供最佳性能。在这种情况下,PL/SQL 单元的源代码会直接编译为给定平台的对象代码。此对象代码链接到 Oracle AI Database。
PL/SQL 引擎定义、编译和运行 PL/SQL 单元。此引擎是许多 Oracle 产品(包括 Oracle AI Database)的特殊组件。虽然许多 Oracle 产品都有 PL/SQL 组件,但本主题专门介绍了 PL/SQL 单元,这些单元可以存储在 Oracle AI Database 中并使用 Oracle AI Database PL/SQL 引擎进行处理。每个 Oracle 工具的文档介绍了其 PL/SQL 功能。
下图显示了 Oracle AI Database 中包含的 PL/SQL 引擎。
图 3:PL/SQL 引擎和 Oracle AI Database

PL/SQL 单元存储在数据库中。应用程序调用存储过程时,数据库会将编译的 PL/SQL 单元加载到系统全局区 (system global area,SGA) 中的共享池中。PL/SQL 和 SQL 语句执行程序协同工作以处理过程中的语句。
可以从其他 PL/SQL 块(可以是匿名块,也可以是其他存储过程)中调用存储过程。例如,您可以从 Oracle Forms 调用存储过程。
在 Oracle AI Database 上执行的 PL/SQL 过程可以调用外部过程或函数用 C 语言编写并存储在共享库中。C 例程在不同于 Oracle AI Database 的单独地址空间中运行。
另请参见:
-
“共享池”以详细了解共享池的用途和内容
-
Oracle AI Database PL/SQL Language Reference(了解有关 PL/SQL 体系结构的信息)
-
Oracle AI Database Development Guide,了解有关外部过程的更多信息
Oracle AI Database 中的 Java 概览
Java 已经成为首选的面向对象的编程语言。
Java 包括以下功能:
-
Java Virtual Machine (JVM),为平台独立性奠定基础
-
自动化存储管理技术,例如垃圾收集
-
借鉴 C 语言并强制强键入的语言语法 注:本章假定您对 Java 语言有所熟悉。
该数据库为 Java 程序提供了一个动态数据处理引擎,支持复杂查询和多个数据视图。客户机请求作为数据查询进行汇编,以便立即进行处理。查询结果是动态生成的。
Java 和 Oracle AI Database 的组合可帮助您创建基于组件的、以网络为中心的应用,这些应用可以随着业务需求的变化轻松更新。此外,您可以将应用程序和数据存储从桌面移至智能网络和以网络为中心的服务器。更重要的是,您可以从任何客户端设备访问这些应用程序和数据存储。
下图显示了传统的双层客户机/服务器配置,其中客户机以调用 PL/SQL 子程序的方式调用 Java 存储过程。
图 4:双层客户机/服务器配置

-
Java Virtual Machine (JVM) 概述 JVM 是运行已编译 Java 代码的虚拟处理器。
-
Java 编程环境 Oracle 为企业应用开发人员提供了用于创建、部署和管理 Java 应用的端到端 Java 解决方案。另请参阅: Oracle AI Database 入门 Java 开发,了解如何将 Java 与 Oracle AI Database 结合使用
Java Virtual Machine (JVM) 概述
JVM 是运行已编译 Java 代码的虚拟处理器。
Java 源代码可编译为与平台无关的低级计算机指令(称为字节码)。Java 字节码通过 JVM 解释为与平台相关的操作。
-
Oracle JVM 概览 Oracle JVM 是一个与 Java 兼容的标准环境,可运行任何纯 Java 应用程序。它与 JLS 和 JVM 规范兼容。
-
Oracle JVM 的主要组件 Oracle JVM 通过共享内存堆并直接访问其关系数据,在与数据库内核相同的进程空间和地址空间中运行。此设计可优化内存使用并提高吞吐量。
Oracle JVM 概览
Oracle JVM 是一个与 Java 兼容的标准环境,可运行任何纯 Java 应用程序。它与 JLS 和 JVM 规范兼容。
Oracle JVM 支持标准的 Java 二进制格式和 API。此外,Oracle AI Database 还遵循标准 Java 语言语义,包括运行时动态类加载。
下图说明 Oracle Java 应用程序如何位于 Java 核心类库之上,这些库位于 Oracle JVM 之上。由于 Oracle Java 支持系统位于数据库内,因此 JVM 会与数据库库交互,而不是直接与操作系统交互。
图 5:Java 组件结构

与其他 Java 环境不同,Oracle JVM 嵌入在 Oracle AI Database 中。Oracle JVM 与典型客户机 JVM 之间存在一些重要差异。例如,在标准 Java 环境中,可以通过解释器运行 Java 应用程序,方法是在命令行上发出以下命令,其中 classname 是 JVM 首先解释的类的名称:
java classname
上述命令将导致应用程序在操作系统上的进程内运行。但是,如果不使用命令行界面,则必须将应用程序加载到数据库中,发布该界面,然后在数据库数据字典中运行该应用程序。
另请参阅:有关 Oracle JVM 与典型客户机 JVM 之间的其他差异的说明,请参阅 Oracle AI Database Java Developer’s Guide
Oracle JVM 的主要组件
Oracle JVM 通过共享内存堆并直接访问其关系数据,在与数据库内核相同的进程空间和地址空间中运行。此设计可优化内存使用并提高吞吐量。
Oracle JVM 为 Java 对象提供了运行时环境。它完全支持 Java 数据结构、方法分派、异常处理和语言级线程。它还支持所有核心 Java 类库,包括 java.lang、java.io、java.net、java.math 和 java.util。
下图显示了 Oracle JVM 的主要组件。
图 6:Oracle JVM 的主要组件

Oracle JVM 将标准 Java 名称空间嵌入到数据库方案中。通过此功能,Java 程序可以访问存储在整个企业的 Oracle AI Database 和应用服务器中的 Java 对象。
此外,Oracle JVM 还与数据库的可伸缩共享内存体系结构紧密集成。Java 程序无需用户干预即可高效地使用调用、会话和对象生命周期。因此,即使 Oracle JVM 和中间层 Java 业务对象处于会话长状态,也可以进行缩放。
另请参阅: Oracle AI Database Java Developer’s Guide,了解 Oracle JVM 主要组件的说明
Java 编程环境
Oracle 为企业应用开发人员提供了用于创建、部署和管理 Java 应用的端到端 Java 解决方案。
该解决方案包括客户端和服务器端编程接口、支持 Java 开发的工具以及与 Oracle AI Database 集成的 Java Virtual Machine。所有这些产品都与 Java 标准兼容。
Java 编程环境包含以下附加功能:
-
Java 存储过程作为 PL/SQL 的 Java 等效项和伙伴。Java 存储过程与 PL/SQL 紧密集成。可以从 PL/SQL 程序包中调用 Java 存储过程,从 Java 存储过程调用过程。
-
用于访问 SQL 数据的 JDBC 和 SQLJ 编程接口。
-
用于帮助开发、加载和管理课程的工具和脚本。
-
Java 存储过程 Java 存储过程是发布到 SQL 并存储在数据库中的 Java 方法。
-
Java 和 PL/SQL 集成 您可以从 PL/SQL 中的 Java 和 Java 程序调用现有的 PL/SQL 程序。此解决方案可保护和利用您的 PL/SQL 和 Java 代码。
Java 存储过程
Java 存储过程是发布到 SQL 并存储在数据库中的 Java 方法。
与 PL/SQL 子程序一样,Java 过程可以直接与 SQL*Plus 等产品一起调用,也可以通过触发器间接调用。您可以从任何 Oracle Net 客户端 -OCI、预编译器或 JDBC 访问它。
要发布 Java 方法,需要编写调用规范,将 Java 方法名称、参数类型和返回类型映射到其 SQL 对应对象。当客户机应用程序调用时,Java 存储过程可以接受参数、引用 Java 类并返回 Java 结果值。
通过引用调用规范的名称来调用 Java 方法的应用程序。运行时系统在 Oracle 数据字典中查找调用规范定义并运行相应的 Java 方法。
此外,您还可以使用 Java 开发独立于 PL/SQL 的强大程序。Oracle AI Database 提供了完全合规的 Java 编程语言和 JVM 实施。
另请参阅:Oracle AI Database Java Developer’s Guide 介绍了如何用 Java 编写存储过程,如何从 PL/SQL 访问这些过程,以及如何从 Java 访问 PL/SQL 功能
Java 和 PL/SQL 集成
可以从 PL/SQL 中的 Java 和 Java 程序调用现有的 PL/SQL 程序。此解决方案可保护和利用您的 PL/SQL 和 Java 代码。
Oracle AI Database 提供了 JDBC,可用于从客户端和服务器上的 Java 访问 SQL 数据。
- JDBC 驱动程序 JDBC 是一种数据库访问协议,允许您连接到数据库,并运行 SQL 语句和查询到数据库。
JDBC 驱动程序
JDBC 是一种数据库访问协议,允许您连接到数据库并运行 SQL 语句和查询到数据库。
核心 Java 类库仅提供一个 JDBC API java.sql。但是,JDBC 旨在使供应商能够提供驱动程序,为特定数据库提供必要的专业化。Oracle 提供了下表中显示的不同 JDBC 驱动程序。
表 2 JDBC 驱动程序
| 驾驶员 | 说明 |
|---|---|
| JDBC 瘦驱动程序 | 可以使用 JDBC Thin 驱动程序编写访问 Oracle SQL 数据的纯 Java 应用程序和小程序。JDBC Thin 驱动程序特别适合基于 Web 的应用程序和小程序,因为您可以从 Web 页(类似于任何其他 Java 小程序)动态下载它。 |
| JDBC OCI 驱动程序 | JDBC OCI 驱动程序访问 Oracle 特定的原生代码(即客户端或中间层上的非 Java 代码和库),与 JDBC Thin 驱动程序相比,性能提高了,但成本要大得多,并且客户端安装也大大提高了。 |
| JDBC 服务器端内部驱动程序 | 在服务器上运行 Java 代码时,Oracle AI Database 使用服务器端内部驱动程序。它允许在服务器上的 Oracle JVM 中运行的 Java 应用程序通过 JDBC 访问本地定义的数据,即同一系统上和同一进程中的数据。它可以提高性能,因为它能够直接使用底层 Oracle RDBMS 库,而不会产生 Java 代码和 SQL 数据之间介入网络连接的开销。通过在服务器上支持相同的 Java-SQL 接口,Oracle AI Database 不需要在部署代码时对其进行返工。 |
另请参见:
Oracle AI Database 中的 JavaScript 概述
JavaScript 是当今最流行的编程语言之一。在 Linux x86-64 或 Linux aarch64 上部署的 Oracle AI Database 将 JavaScript 添加到服务器端开发支持的语言列表中。
您可以将 JavaScript 的模块存储在数据库中,处理它所处的数据,这可能比客户端开发方法带来重大改进。JavaScript 由 Multilingual Engine (MLE) 执行。
开发人员可以选择执行独立的 JavaScript 代码和将 JavaScript 代码原生存储在数据库中作为模块。
-
将业务逻辑存储为数据库中的模块与客户端开发相关的 JavaScript 一样,代码可以以模块的形式一起存储。
-
动态执行 JavaScript 代码 框架开发人员和希望执行独立 JavaScript 代码而无需在数据库中存储代码的任何人都可以使用
DBMS_MLE软件包及其子例程。 -
Inline JavaScript Stored Procedures 内联 MLE 调用规范直接嵌入
CREATE FUNCTION和CREATE PROCEDUREDDL 中的 JavaScript 代码。另请参阅:Oracle AI Database JavaScript Developer’s Guide,详细了解 Oracle AI Database 中的 JavaScript 支持。
将业务逻辑存储为数据库中的模块
与客户端开发相关的 JavaScript 一样,代码可以以模块的形式一起存储。
具有 PL/SQL 背景的开发人员可以将 JavaScript 模块视为等效于 PL/SQL 程序包主体,但是在 JavaScript 中编写。可以将模块中声明的函数标记为导出或保持专用。
Oracle AI Database 中的 JavaScript 遵循 ECMAScript 2023 标准,为开发人员提供了在数据库中存储业务逻辑的各种可能性。
注意:
另请参见:
-
《Oracle AI Database JavaScript Developer’s Guide 》第 2 章,全面介绍 MLE 模块。
-
有关调用规范的详细信息,请参见《Oracle AI Database JavaScript Developer’s Guide 》第 5 章。
下面是使用 MLE 创建 JavaScript 模块的示例:
create mle module if not exists example_module
language javascript as
export function string2obj(inputString) {
if ( inputString === undefined ) {
throw `must provide a string in the form of key1=value1;...;keyN=valueN`;
}
let myObject = {};
if ( inputString.length === 0 ) {
return myObject;
}
const kvPairs = inputString.split(";");
kvPairs.forEach( pair => {
const tuple = pair.split("=");
if ( tuple.length === 1 ) {
tuple[1] = false;
} else if ( tuple.length != 2 ) {
throw "parse error: you need to use exactly one '=' between key and value and not use '=' in either key or value";
}
myObject[tuple[0]] = tuple[1];
});
return myObject;
}
/
JavaScript 模块(也称为 MLE 模块)现在存储在用户的方案中。其唯一函数 string2obj() 可以通过创建调用规范向 SQL 和 PL/SQL 公开。调用规范是 PL/SQL 程序单元,允许您在可以调用 SQL 和 PL/SQL 的任何位置调用 JavaScript 代码。可以按如下方式编写 string2obj() 的调用规范:
create function if not exists p_string_to_JSON(p_str varchar2) return JSON
as mle module example_module
signature 'string2obj(string)';
/
通过创建函数,可以从 SQL 调用该函数:
declare
l_json JSON;
l_string VARCHAR2(100);
begin
l_string := 'a=1;b=2;c=3;d';
l_json := p_string_to_JSON(l_string);
dbms_output.put_line(json_serialize(l_json PRETTY));
end;
/
{
"a" : "1",
"b" : "2",
"c" : "3",
"d" : false
}
PL/SQL procedure successfully completed.
动态执行 JavaScript 代码
框架开发人员和任何希望执行独立 JavaScript 代码而无需在数据库中存储代码的人都可以利用 DBMS_MLE 软件包及其子例程。
例如,Oracle Application Express 和 Database Actions 集成 DBMS_MLE,隐藏在封面下调用 PL/SQL 程序包的事实。
与 MLE 模块相比,使用 DBMS_MLE 会使编写整个应用程序变得更加困难。例如,在逻辑上将应用程序划分为单独的实体更难。执行后调试功能需要模块,因此更难排除代码片段中的问题。连续集成 (Continuous Integration,CI) 管道还可能难以在同一个文件中使用 linting PL/SQL 和 JavaScript 代码。同样,集成开发环境 (Integrated Development Environment,IDE) 也可能存在问题,因为大多数开发人员很难在同一窗口中同时使用 PL/SQL 和 JavaScript。
注意:
另请参见:
-
Oracle AI Database PL/SQL Packages and Types Reference(了解有关
DBMS_MLE及其子例程的更多详细信息)。 -
有关动态 JavaScript 调用的更多详细信息,请参见Oracle AI Database JavaScript Developer’s Guide 第 3 章。
内嵌 JavaScript 存储过程
内联的 MLE 调用规范直接嵌入 CREATE FUNCTION 和 CREATE PROCEDURE DDL 中的 JavaScript 代码。
如果要使用 JavaScript 快速实现简单功能,内联 MLE 调用规范可能是一个不错的选择。使用此选项,您无需部署包含 JavaScript 代码的单独模块。相反,JavaScript 函数内置在调用规范本身的定义中。
MLE LANGUAGE 子句用于指定使用 JavaScript 实现函数。语言名称后面的字符串被视为实现调用规范功能的 JavaScript 函数的正文。执行代码时,PL/SQL 参数将自动转换为默认的 JavaScript 类型,并作为同名的参数传递到 JavaScript 函数。请注意,不带引号的参数名称将映射到全大写 JavaScript 名称。JavaScript 函数返回的值将转换为 PL/SQL 调用规范的返回类型,就像 MLE 模块的调用规范一样。
触发器概览
数据库触发器是使用 PL/SQL、Java 或 JavaScript 编写的、Oracle Database 在某些情况下自动调用的已编译存储程序单元(“触发”)。
只要发生以下操作之一,就会触发触发器:
-
特定表或视图上的 DML 语句,由任何用户发出
DML 语句修改方案对象中的数据。例如,插入和删除行就是 DML 操作。
-
特定用户或任何用户发出的 DDL 语句
DDL 语句定义方案对象。例如,创建表和添加列就是 DDL 操作。
-
数据库活动
用户登录或注销、错误以及数据库启动或关闭是可调用触发器的事件。
触发器是与子程序相似但调用方式不同的方案对象。子程序由用户、应用程序或触发器显式运行。发生触发事件时,数据库会隐式调用触发器。
-
触发器的优点通过正确使用触发器,您可以构建和部署更强大、更有效地使用数据库的应用程序。
-
触发器的类型可以根据其调用方式及其执行的操作类型对触发器进行分类。
-
触发器的计时 您可以定义触发计时,无论是在触发语句之前还是在之后运行触发操作。
-
创建触发器
CREATE TRIGGER语句创建或替换数据库触发器。 -
触发器执行 Oracle Database 在内部使用与子程序执行相同的步骤执行触发器。
-
存储触发器 Oracle Database 将 PL/SQL 触发器以编译后的形式存储在数据库方案中,就像 PL/SQL 存储过程一样。
另请参见:
-
“ SQL 语句概览”了解 DML 和 DDL
触发器的优点
通过正确使用触发器,可以构建和部署更强大、更有效地使用数据库的应用程序。
可以使用触发器执行以下操作:
-
自动生成派生列值
-
防止无效事务处理
-
提供审计和事件日志记录
-
有关表访问权限的记录信息
可以使用触发器对所有客户端应用程序强制实施通用的低级别业务规则。例如,多个应用程序可以访问 employees 表。如果此表中的触发器确保插入数据的格式,则不需要在每个客户机中复制此业务逻辑。由于应用程序无法规避触发器,因此会自动使用触发器中的业务逻辑。
可以使用触发器和完整性约束条件来定义和强制实施任何类型的完整性规则。但是,Oracle 强烈建议您仅使用触发器来强制使用完整性约束条件无法定义的复杂业务规则。
过多使用触发器可能会导致复杂的相互依赖性,这在大型应用程序中可能难以维护。例如,当调用触发器时,其触发器操作中的 SQL 语句可能会触发其他触发器,从而导致级联触发器,从而产生意外效果。
另请参见:
-
“数据完整性简介”
-
Oracle AI Database PL/SQL Language Reference(了解为应用程序规划触发器时的准则和限制)
在某些情况下自动”。
触发器类型
可以根据触发器的调用方式及其执行的操作类型对触发器进行分类。
Oracle Database 支持以下类型的触发器:
-
行触发器
每次表受触发语句影响时,行触发器都会触发。例如,如果一条语句更新了多个行,则对于受
UPDATE影响的每一行,一个行触发器都会触发一次。如果触发器语句不影响行,则不运行行触发器。如果触发器操作中的代码取决于触发器语句提供的数据或受影响的行,则行触发器非常有用。 -
报表触发器
代表触发语句触发一次语句触发器,而不考虑受触发语句影响的行数。例如,如果某个语句从表中删除了 100 行,则仅触发一次语句级别的
DELETE触发器。如果触发器操作中的代码不依赖于触发器语句提供的数据或受影响的行,则语句触发器非常有用。 -
INSTEAD OF触发器Oracle Database 触发了 INSTEAD OF 触发器,而不是执行触发语句。这些触发器对于透明地修改无法通过 DML 语句直接修改的视图非常有用。
-
事件触发器
可以使用触发器向订户发布有关数据库事件的信息。事件触发器分为以下类别:
在某些情况下自动”。
触发器的计时
可以定义触发器计时 - 触发器操作是在触发语句之前还是之后运行。
简单触发器是表中的单个触发器,可用于仅为以下某个计时点指定操作:
-
在解雇声明之前
-
在受触发语句影响的每一行之前
-
在受触发语句影响的每一行之后
-
解雇声明之后
对于语句和行触发器,BEFORE 触发器可以在对数据库进行更改之前增强安全性并启用业务规则。AFTER 触发器非常适合记录操作。
复合触发器可在多个时间点触发。复合触发器有助于编程一种方法,在这种方法中,针对各种计时点执行的操作共享通用数据。
另请参阅:Oracle AI Database PL/SQL Language Reference 以了解复合触发器
在某些情况下自动”。
创建触发器
CREATE TRIGGER 语句创建或替换数据库触发器。
PL/SQL 触发器具有以下常规语法形式:
CREATE TRIGGER trigger_name
triggering_statement
[trigger_restriction]
BEGIN
triggered_action;
END;
PL/SQL 触发器具有以下基本组件:
-
触发器名
该名称在同一方案中的其他触发器名称中必须唯一。例如,名称可以是
part_reorder_trigger。 -
触发器事件或语句
触发事件或语句是导致调用触发器的 SQL 语句、数据库事件或用户事件。例如,用户更新表。
-
触发器限制
触发器限制指定为使触发器触发的布尔 expression 必须为
true。例如,除非可用部件数小于当前再订购数量,否则不会调用触发器。 -
触发的操作
触发的操作是包含发出触发语句且触发器限制求值结果为 true 时要运行的 SQL 语句和代码的过程。例如,用户在待定订单表中插入一行。
-
示例:CREATE TRIGGER 语句 此示例创建在对行项目表执行
INSERT、UPDATE或DELETE语句时触发的触发器。 -
实例:调用行层触发器在此方案中,客户启动两个订单,然后从订单中添加和删除行项目。
另请参见:
-
Oracle AI Database 入门 Oracle AI Database Development 和 Oracle AI Database PL/SQL Language Reference,了解如何创建触发器
-
Oracle AI Database SQL Language Reference,了解
CREATE TRIGGER语句
在某些情况下自动”。
示例:CREATE TRIGGER 语句
此示例创建在对行项目表执行 INSERT、UPDATE 或 DELETE 语句时触发的触发器。
假设您使用以下语句创建了 orders 和 lineitems 表。orders 表针对每个唯一顺序包含一行,而 lineitems 表针对每个顺序包含一行。
CREATE TABLE orders
( order_id NUMBER PRIMARY KEY,
/* other attributes */
line_items_count NUMBER DEFAULT 0 );
CREATE TABLE lineitems
( order_id REFERENCES orders,
seq_no NUMBER,
/* other attributes */
CONSTRAINT lineitems PRIMARY KEY(order_id,seq_no) );
以下语句将创建一个示例触发器,该触发器将按顺序自动使用项目数更新 orders 表:
CREATE OR REPLACE TRIGGER lineitems_trigger
AFTER INSERT OR UPDATE OR DELETE ON lineitems
FOR EACH ROW
BEGIN
IF (INSERTING OR UPDATING)
THEN
UPDATE orders SET line_items_count = NVL(line_items_count,0)+1
WHERE order_id = :new.order_id;
END IF;
IF (DELETING OR UPDATING)
THEN
UPDATE orders SET line_items_count = NVL(line_items_count,0)-1
WHERE order_id = :old.order_id;
END IF;
END;
/
在 lineitems_trigger 中,触发语句是 lineitems 表上的 INSERT、UPDATE 或 DELETE。不存在触发限制。为更改的每个行调用触发器。触发器有权访问受触发语句影响的当前行的旧列和新列值。要修改的表的每一列都存在两个相关名称:旧值 (:old) 和新值 (:new)。如果会话为订单更新或插入 lineitems 中的行,则在操作之后,触发器将计算此订单中的项目数并使用计数更新 orders 表。
示例:调用行级触发器
在此方案中,客户启动两个订单,然后从订单中添加和删除行项目。
该方案基于在示例:CREATE TRIGGER 语句中创建的触发器。
表 3 行级触发器方案
| SQL 语句 | 触发的 SQL 语句 | 说明 |
|---|---|---|
SQL> INSERT INTO orders (order_id) VALUES (78); 1 row created. |
客户创建 ID 为 78 的订单。此时,客户在订单中没有商品。 由于不对 |
|
SQL> INSERT INTO orders (order_id) VALUES (92); 1 row created. |
客户创建 ID 为 92 的单独订单。此时,客户在订单中没有商品。 由于不对 |
|
SQL> INSERT INTO lineitems (order_id, seq_no) VALUES (78,1); 1 row created. |
UPDATE orders SET line_items_count = NVL(NULL,0)+1 WHERE order_id = 78; |
客户将货品添加到订单 78。
|
SQL> INSERT INTO lineitems (order_id, seq_no) VALUES (78,2); 1 row created. |
UPDATE orders SET line_items_count = NVL(1,0)+1 WHERE order_id = 78; |
客户将附加商品添加到订单 78。
|
SQL> SELECT * FROM orders; ORDER_ID LINE_ITEMS_COUNT --------- ---------------- 78 2 92 0 |
客户查询两个订单的状态。第 78 章有两件事订单 92 不包含任何商品。 | |
SQL> SELECT * FROM lineitems; ORDER_ID SEQ_NO ---------- ---------- 78 1 78 2 |
客户查询行项目的状态。每个货品都由订单 ID 和序号唯一标识。 | |
SQL> UPDATE lineitems SET order_id = 92; 2 rows updated. |
UPDATE orders SET line_items_count = NVL(NULL,0)+1 WHERE order_id = 92; UPDATE orders SET line_items_count = NVL(2,0)-1 WHERE order_id = 78; UPDATE orders SET line_items_count = NVL(1,0)+1 WHERE order_id = 92; UPDATE orders SET line_items_count = NVL(1,0)-1 WHERE order_id = 78; |
客户将订单 78 中的行项目移至订单 92。
每次调用触发器时,都会满足触发器中的两个 |
SQL> SELECT * FROM orders; ORDER_ID LINE_ITEMS_COUNT --------- ---------------- 78 0 92 2 |
客户查询两个订单的状态。净影响是订单 92 的行项目计数从 0 增加到 2,而订单 78 的计数从 2 减少到 0。 | |
SQL> SELECT * FROM lineitems; ORDER_ID SEQ_NO ---------- ---------- 92 1 92 2 |
客户查询行项目的状态。每个货品都由订单 ID 和序号唯一标识。 | |
SQL> DELETE FROM lineitems; 2 rows deleted. |
UPDATE orders SET line_items_count = NVL(2,0)-1 WHERE order_id = 92; UPDATE orders SET line_items_count = NVL(1,0)-1 WHERE order_id = 92; |
客户现在从所有订单中删除所有行项目。
|
SQL> SELECT * FROM orders; ORDER_ID LINE_ITEMS_COUNT --------- ---------------- 78 0 92 0 SQL> SELECT * FROM lineitems; no rows selected |
客户查询两个订单的状态。订单均不包含行项目。 客户还查询行项目的状态。不存在项。 |
执行触发器
Oracle Database 在内部使用与子程序执行相同的步骤执行触发器。
唯一的微妙区别是,如果用户帐户具有运行触发语句的权限,则其有权触发触发器。除此之外,数据库将验证并运行触发器的方式与存储的子程序相同。
另请参阅:Oracle AI Database PL/SQL Language Reference 以了解有关触发器执行的更多信息
在某些情况下自动”。
触发器的存储
Oracle Database 将 PL/SQL 触发器以编译形式存储在数据库方案中,就像 PL/SQL 存储过程一样。
提交 CREATE TRIGGER 语句时,编译的 PL/SQL 代码将存储在数据库中。共享池将删除 PL/SQL 触发器的源代码。
下图显示了具有隐式调用 PL/SQL 触发器的 SQL 语句的数据库应用程序。触发器与其关联的表分开存储。
图 7:触发器

Java 触发器以与 PL/SQL 触发器相同的方式存储。但是,Java 触发器引用了使用 CALL 语句单独编译的 Java 代码。因此,创建 Java 触发器包括创建 Java 代码和创建引用此 Java 代码的触发器。
另请参阅:Oracle AI Database PL/SQL Language Reference 以了解如何编译和存储触发器
在某些情况下自动”。