伺服器端程式設計:PL/SQL、Java 以及 JavaScript
SQL 說明結構化查詢語言 (SQL) 語言,以及資料庫如何處理 SQL 敘述句。本章說明儲存在資料庫中的程序語言 /SQL (PL/SQL) 或 Java 程式如何使用 SQL。
-
伺服器端程式設計簡介在非程序語言 (例如 SQL) 中,指定要操作的資料集,但不指定要執行的作業,或將執行作業的方式。
-
PL/SQL 簡介 PL/SQL 提供易於使用的伺服器端預存程序語言,與 SQL、強大、可攜式且安全無縫接軌。您可以使用程序物件 (稱為 PL/SQL 單位 ) 來存取和操控資料庫資料。
-
Oracle AI Database 中的 Java 概要 Java 已成為所選的物件導向程式設計語言。
-
Oracle AI Database 中的 JavaScript 簡介 JavaScript 是當今最受歡迎的程式設計語言之一。部署在 Linux x86-64 或 Linux aarch64 上的 Oracle AI Database,會將 JavaScript 新增至伺服器端開發支援的語言清單中。
-
觸發程式簡介資料庫觸發程式是編譯的預存程式單元,以 PL/SQL、Java 或 JavaScript 撰寫,Oracle Database 會在特定情況下自動呼叫 ("fires")。另請參閱:SQL ,瞭解 SQL 語言簡介。
伺服器端程式設計簡介
在非程序語言 (例如 SQL) 中,指定要操作的資料集,但不會指定要執行的作業或執行作業的方式。
在程序語言程式中,大多數的敘述句執行取決於先前或後續的敘述句,以及 SQL 中無法使用的控制結構 (例如迴圈或條件分支)。如需程序語言與非程序語言之間的差異說明,假設下列 SQL 敘述句查詢 employees 表格:
SELECT employee_id, department_id, last_name, salary FROM employees;
前面的陳述式會要求資料,但不會對資料套用邏輯。不過,假設您希望應用程式決定資料集中的每位員工是否應依據薪資和部門績效來加薪。提高的必要條件是員工在過去五年內未收到超過三次的加薪。若呼叫加薪,則應用程式必須調整薪資,並以電子郵件傳送給經理人員;否則,應用程式必須更新報告。
問題在於需要條件邏輯和程式流程控制的程序資料庫應用程式如何使用 SQL。基本開發方法如下:
-
使用從屬端程式設計來將 SQL 敘述句內嵌在以程序語言 (例如 C、C++ 或 Java) 撰寫的應用程式中
您可以在編譯之前,將 SQL 敘述句置於原始程式碼中,並將它送出至 precompiler 或 Java 轉譯器。或者,您可以排除預先編譯步驟,並使用 Java 資料庫連線 (JDBC) 或 Oracle Call Interface (OCI) 等 API,讓應用程式能夠與資料庫互動。
-
使用伺服器端程式設計來開發位於資料庫中的資料邏輯
應用程式可以明確呼叫以 PL/SQL (宣告的 P L 序列 ) Java 或 JavaScript 撰寫的預存子程式 (程序和函數)。您也可以建立觸發程式,此觸發程式是儲存於資料庫中的具名程式單元,並呼叫以回應指定的事件。
本章說明第二種方法。伺服器端程式設計的主要優點是,內建於資料庫的功能可以在任何位置部署。資料庫而非應用程式會決定在指定作業系統上執行作業的最佳方式。此外,子程式透過集中伺服器上的應用程式處理來提高可擴展性,讓用戶端可以重複使用程式碼。由於子程式呼叫既快速又有效率,因此單一呼叫可以啟動需要大量運算的預存子程式,從而減少網路流量。
您可以使用下列語言將資料邏輯儲存在 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 類似的執行模型與 SQL 的 Java 預存子程式介面。
-
JavaScript
當部署在 Linux x86-64 或 Linux aarch64 上時,Oracle AI Database 可讓開發人員在 JavaScript 中表達業務邏輯。DBMS_MLE PL/SQL 套裝程式及其子常式可以執行 JavaScript 特別執行。將商業邏輯儲存為 JavaScript 綱要物件可讓您撰寫更複雜的應用程式。呼叫設定會以類似 Java 預存程序的方式,顯示儲存在 SQL 和 PL/SQL 資料庫中的 JavaScript 程式碼。
另請參閱:
-
Oracle AI Database 開發指南,瞭解如何使用預先編譯器和 API 內嵌 SQL
-
Oracle AI Database 開始使用 Oracle AI Database 開發,瞭解 Oracle AI Database 應用程式開發簡介
-
Oracle AI Database Development Guide,瞭解如何選擇程式設計環境
-
Oracle AI Database JavaScript 開發人員指南,深入瞭解 Oracle AI Database 中的 JavaScript 支援。
PL/SQL 概要
PL/SQL 提供易於使用的伺服器端預存程序語言,與 SQL、強大、可攜式且安全無縫。您可以使用程序物件 (稱為 PL/SQL 單位 ) 來存取和操控資料庫資料。
PL/SQL 單位一般分類如下:
-
PL/SQL 子程式是儲存在資料庫中的 PL/SQL 區塊,可以透過應用程式的名稱來呼叫。當您建立子程式時,資料庫會剖析子程式,並將其剖析表示儲存在資料庫中。您可以將子程式宣告為程序或函數。
-
PL/SQL 匿名區塊是出現在您應用程式中的 PL/SQL 區塊,而非在資料庫中命名或儲存。在許多應用程式中,無論 SQL 敘述句的出現位置,PL/SQL 區塊都會出現。
PL/SQL 編譯器和解譯器內嵌在 Oracle SQL Developer 中,可讓開發人員在從屬端和伺服器上使用一致的開發模型。此外,PL/SQL 預存程序可以從數個資料庫從屬端 (例如 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 Collections and Records 許多程式設計技術都使用陣列、包裝袋、清單、巢狀表格、集合和樹狀結構等集合類型。
-
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 子程式的優點
與用戶端程式設計相比,伺服器端程式設計具有許多優點。
優點包括:
-
效能提升
-
記憶體配置
由於預存程序會利用 Oracle AI Database 的共用記憶體功能,因此它只能將單一程序複本載入記憶體中,以供多位使用者執行。在使用者之間共用程式碼可大幅減少應用程式的資料庫記憶體需求。
-
提高生產力
預存程序可提高開發生產力。透過設計通用程序集的相關應用程式,您可以避免多餘的程式碼編寫。例如,您可以撰寫程序來操控
employees表格中的資料列。任何應用程式都可以呼叫這些程序,而不需要重新撰寫 SQL 敘述句。如果資料管理方法變更,則僅必須修改程序,而非使用程序的應用程式。預存程序可能是達到程式碼重複使用的最佳方式。因為任何以任何語言編寫的從屬端應用程式都可以呼叫預存程序,所以它們可以在所有環境中重複使用程式碼。
-
完整性
預存程序可改善應用程式的完整性和一致性。透過使用常見的程序群組來開發應用程式,可以降低編碼錯誤的可能性。
例如,您可以測試子程式以保證它會傳回準確的結果,並在驗證之後,在任意數量的應用程式中重複使用該子程式,而不需要重新測試。如果變更程序所參照的資料結構,則您只能重新編譯程序。呼叫程序的應用程式不一定需要修改。
-
具定義者權利程序的安全性
預存程序可協助強制執行資料安全性。定義者的權限 PL/SQL 程序會以其擁有者的權限執行,而不是以目前的使用者執行。因此,您可以限制使用者執行的資料庫工作,方法是只允許使用者透過以定義者權限執行的程序和功能來存取資料。
例如,您可以授予使用者更新表格之程序的存取權,但不能授予表格本身的存取權。當使用者呼叫程序時,它會以其擁有者的權限執行。只有執行程序的權限 (但沒有從基礎表格查詢、更新或刪除的權限) 的使用者可以呼叫程序,但無法以任何其他方式操控表格資料。
-
繼承的權限和綱要相關資訊環境與呼叫者的權限程序
呼叫者的權限 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 Oracle AI Database Development 入門,瞭解如何建立子程式
-
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 Development,深入瞭解 SQL*Plus 和 SQL Developer
-
Oracle AI Database Development Guide,瞭解有關預先編譯器的詳細資訊
-
Oracle AI Database PL/SQL Language Reference,瞭解如何使用 PL/SQL 子程式
-
SQL*Plus User's Guide and Reference,瞭解
EXECUTE命令
PL/SQL 套裝程式
PL/SQL 套裝程式是一組相關的子程式,以及它們使用的游標和變數,儲存在資料庫中以繼續作為單位使用。套裝程式子程式可由應用程式或使用者明確呼叫。
Oracle AI Database 包含許多提供的套裝程式,可擴充資料庫功能並提供 PL/SQL 存取 SQL 功能。例如,UTL_HTTP 套裝程式可讓 PL/SQL 和 SQL 的 HTTP 對外呼叫存取網際網路上的資料或呼叫 Oracle Web Server 磁帶匣。您可以在建立應用程式時使用提供的套裝程式,或在建立自己的預存程序時作為想法來源。
-
PL/SQL 套裝程式的優點 PL/SQL 套裝程式可為應用程式開發人員提供許多優點。
-
建立 PL/SQL 套裝程式:您可以在兩個部分建立套裝程式:規格和主體。套裝程式設定會宣告套裝程式的所有公用建構項目,套裝程式主體則定義套裝程式的所有建構項目 (公用和專用)。
-
執行 PL/SQL 套裝程式子程式資料庫觸發程式、預存子程式、3GL 應用程式和 Oracle 工具都可以參照套裝程式內容。
PL/SQL 套裝程式的優點
PL/SQL 套裝程式可為應用程式開發人員提供一些優點。
優點包括:
-
封裝
套裝軟體可讓您將預存程序、變數、資料類型等項目封裝或分組在已命名的預存單位中。封裝可在開發期間提供較佳的組織,同時也提供更多的彈性。您可以建立規格並參照公用程序,而不需要實際建立套裝程式主體。封裝可簡化權限管理。授與套裝程式的權限會讓受權者能夠存取套裝程式建構。
-
資料保全
套裝程式定義方法可讓您指定哪些變數、游標以及程序是公用和專用。「公用」表示套裝程式的使用者可以直接存取它。「專用」表示對套裝程式的使用者而言是隱藏的。
例如,套裝軟體可包含 10 個程序。您可以定義套裝程式,讓只有三個程序是公用程序,因此可供套裝程式的使用者執行。其餘程序為專用程序,而且只能由套裝程序內的程序存取。請勿將公用和專用套裝程式變數與授予
PUBLIC混淆。 -
更佳的效能
第一次呼叫套裝軟體中的程序時,會將整個套裝軟體以小區塊形式載入記憶體。此載入在單一作業中完成,相對於獨立程序所需的個別載入。當呼叫相關的封裝程序發生時,在記憶體中執行編譯的程式碼不需要執行磁碟 I/O。
您可以取代並重新編譯套裝程式主體,而不會影響規格。因此,除非同時取代套裝程式設定,否則不需要重新編譯參照套裝程式建構 (一律透過規格) 的綱要物件。透過使用套裝程式,可以將不必要的重新編譯最小化,進而降低對整體資料庫效能的影響。
建立 PL/SQL 套裝程式
您可以在兩個部分建立套裝程式:規格和主體。套裝程式設定會宣告套裝程式的所有公用建構項目,套裝程式主體則定義套裝程式的所有建構項目 (公用和專用)。
下列範例顯示建立 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 敘述句中使用變數或常數,在需要時擷取或提供值。
-
游標
您可以在程序、函數或套裝程式中明確宣告游標,以協助記錄導向的 Oracle AI Database 資料處理。PL/SQL 引擎也可以隱含地宣告游標。
-
例外
PL/SQL 可讓您明確處理 PL/SQL 程式碼處理期間產生的內部和使用者定義的錯誤條件 (稱為異常狀況 )。
PL/SQL 可以執行在程式實際執行之前無法辨識完整文字的動態 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 集合是一個排序的元素群組,全部相同類型。
-
記錄 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 元件,但本主題特別涵蓋可以儲存在 Oracle AI Database 中並使用 Oracle AI Database PL/SQL 引擎處理的 PL/SQL 單位。每項 Oracle 工具的文件說明其 PL/SQL 功能。
下圖說明 Oracle AI Database 中包含的 PL/SQL 引擎。
圖 3:PL/SQL 引擎與 Oracle AI Database

PL/SQL 單元儲存在資料庫中。當應用程式呼叫預存程序時,資料庫會將已編譯的 PL/SQL 單位載入系統整體區域 (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 的組合可協助您建立以元件為基礎的網路為中心應用程式,並隨著業務需求的變化輕鬆更新。此外,您可以將應用程式和資料儲存從桌面移出,並移到智慧型網路和以網路為中心的伺服器上。更重要的是,您可以從任何用戶端裝置存取這些應用程式和資料倉庫。
下圖顯示傳統的兩層從屬端 / 伺服器組態,從屬端呼叫 Java 預存程序的方式與呼叫 PL/SQL 子程式的方式相同。
圖 4:兩層從屬端 / 伺服器組態

-
Java Virtual Machine (JVM) 簡介 JVM 是執行編譯之 Java 程式碼的虛擬處理器。
-
Java 程式設計環境 Oracle 為企業應用程式開發人員提供用於建立、部署和管理 Java 應用程式的端對端 Java 解決方案。另請參閱:Oracle AI Database Java 開發入門,瞭解搭配 Oracle AI Database 使用 Java 的簡介
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 應用程式如何位在 Oracle JVM 的最上層 Java 核心類別程式庫。因為 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 子程式一樣,您可以直接使用 SQL*Plus 等產品呼叫 Java 程序,也可以使用觸發程式間接呼叫。您可以從任何 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 整合
您可以從 Java 和 Java 程式,從 PL/SQL 呼叫現有的 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 驅動程式,撰寫純 Java 應用程式和存取 Oracle SQL 資料的 Applet。JDBC Thin 驅動程式特別適用於 Web 型應用程式和 Applet,因為您可以從網頁動態下載,類似於其他的 Java Applet。 |
| 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套裝程式及其子程式。 -
內嵌 JavaScript 預存程序內嵌 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 Modules。
-
Oracle AI Database JavaScript Developer's Guide 第 5 章,瞭解有關 Call Specifications 的詳細資訊。
以下為使用 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 使撰寫整個應用程式變得更加困難。例如,邏輯上將應用程式劃分成不同的實體是較難的。「執行後除錯」功能需要可讓模組更難排解程式碼片段中的問題。持續整合 (CI) 管線也可能在同一個檔案中列印 PL/SQL 和 JavaScript 程式碼。同樣,您的整合開發環境 (IDE) 可能發生問題,因為大部分問題都會在同一個視窗中同時使用 PL/SQL 和 JavaScript。
備註:
另請參閱:
-
Oracle AI Database PL/SQL Packages and Types Reference,瞭解有關
DBMS_MLE及其子常式的詳細資訊。 -
Oracle AI Database JavaScript Developer's Guide 第 3 章,瞭解有關動態 JavaScript 呼叫的詳細資訊。
內嵌 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 會在特定情況下自動呼叫 ("fires")。
每當發生下列其中一項作業時,就會觸發程式:
-
任何使用者所發出之特定表格或視觀表的 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 敘述句直接修改的視觀表非常有用。
-
事件觸發程式
您可以使用觸發程式將資料庫事件的相關資訊發佈給訂戶。事件觸發器分為下列類別:
自動在某些情況下。」
觸發程式的時間
您可以定義觸發程式計時 - 無論觸發程式動作是在觸發程式敘述句之前或之後執行。
簡單觸發程式是表格上的單一觸發程式,可讓您為下列其中一個計時點指定動作:
-
在 firing 敘述句之前
-
在受到觸發陳述式影響的每個資料列之前
-
在受到 firing 敘述句影響的每個資料列之後
-
firing 敘述句之後
對於陳述式與列觸發器,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 陳述式、資料庫事件,或造成觸發器呼叫的使用者事件。例如,使用者會更新表格。
-
觸發限制
觸發程式限制指定必須為
true的布林表示式,才能觸發程式。例如,除非可用零件的數量小於目前再訂購數量,否則不會呼叫觸發器。 -
觸發的動作
觸發動作的程序包含發出觸發陳述式且觸發器限制評估為 true 時要執行的 SQL 陳述式與程式碼。例如,使用者在待處理訂單表格中插入一列。
-
範例:建立 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,瞭解編譯和儲存觸發程式
在特定情況下自動執行。」