附註:
- 此教學課程需要存取 Oracle Cloud。若要註冊免費帳戶,請參閱開始使用 Oracle Cloud Infrastructure Free Tier 。
- 其使用 Oracle Cloud Infrastructure 證明資料、租用戶以及區間的範例值。完成實驗室時,請將這些值替代為雲端環境特定的值。
探索 Oracle Database 23ai 的 SQL 功能
簡介
我們將在本自學課程中學習 10 項您需要瞭解的功能,以及這些功能如何與現有的對手方進行比較。這些功能包括:
FROM
子句 (選擇性)。- SQL 的
BOOLEAN
。 IF NOT EXISTS
資料定義語言 (DDL) 子句。INSERT
多值。- 新表格
VALUE
建構子。 GROUP BY
子句中的別名。UPDATE
和MERGE
敘述句的RETURNING
子句。UPDATE
和DELETE
中的結合。- 註釋,資料庫物件的新中繼資料。
- 具有 SQL 網域的輕量型物件類型。
目標
-
使用不含
FROM
子句的 SQL:在選取表示式或內建函數時,移除使用FROM
子句的需求,以啟用較簡單的查詢。 -
在 SQL 中導入原生
BOOLEAN
資料類型:運用 SQL 表格、查詢和條件中的原生BOOLEAN
資料類型,以進行更直覺的真 / 假邏輯處理。 -
使用 DDL 敘述句中的
IF NOT EXISTS
:在不進行額外 PL/SQL 檢查的情況下,依條件執行CREATE
和DROP
敘述句,簡化物件建立和刪除邏輯。 -
執行多重值
INSERT
作業:在單一INSERT
敘述句中插入多個資料列,以改善程式碼可讀性並減少往返至資料庫。 -
使用內嵌資料集的表格值建構子:使用
VALUES
建構子直接在 SQL 中建立暫時資料列集,支援MERGE
、SELECT
或比較等作業。 -
GROUP BY 子句中的參照資料欄別名:允許在
GROUP BY
中使用SELECT
別名,而非重複表示式,以增強查詢可讀性。 -
使用
UPDATE
和MERGE
中的RETURNING
子句:直接從UPDATE
和MERGE
敘述句擷取受影響的資料,而不需要後續查詢。 -
在
UPDATE
和DELETE
敘述句中執行結合:直接在UPDATE
和DELETE
作業中使用JOIN
邏輯,以根據相關表格條件修改或移除記錄。 -
使用描述資料加註資料庫物件:使用
ANNOTATION
來儲存描述性描述資料 (例如擁有者、目的) 的文件資料庫物件,以便於維護和自我檢查。 -
使用 SQL 網域定義輕量型物件類型:建立具有限制條件的可重複使用網域類型,以強制多個表格之間的一致性和強式輸入。
必要條件
-
基本 SQL 知識。
-
瞭解 SQL 語法:
SELECT
、INSERT
、UPDATE
、DELETE
、JOIN
、GROUP BY
等。 -
熟悉關聯式資料庫概念和資料類型。
-
-
體驗 Oracle Database 23ai 及其先前版本。
-
瞭解 DDL、資料處理語言 (DML) 及 PL/SQL 如何在 Oracle Database 19c、Oracle Database 21c 及較舊版本中運作。
-
Oracle 特定功能的相關知識,例如
DUAL
、MERGE
、RETURNING INTO
等。
-
-
存取 Oracle Database 23ai 環境。
-
可存取 Oracle Database 23ai (本機設定、雲端執行處理或 Oracle Live SQL)。
-
某些功能 (例如 SQL 網域或
BOOLEAN
) 只能在 Oracle Database 23ai 中運作。
-
-
SQL*Plus、SQLcl 或 GUI 工具 (例如 SQL Developer 或 DataGrip)。可在相容介面執行和測試 SQL 敘述句。
-
PL/SQL 基礎 (適用於進階功能)。用於使用
RETURNING INTO
、程序區塊和處理動態 SQL。 -
限制與資料完整性規則的相關知識。需要瞭解 SQL 網域和表格限制條件。
-
熟悉 Oracle 資料說明視觀表。用於查詢註解或中繼資料。例如,
USER_TABLES
、USER_ANNOTATIONS
。 -
Oracle Database 中的角色和權限。建立 / 更改表格、網域和註釋的能力需要適當的使用者權限。
-
版本意識。確保您的工具和用戶端支援 Oracle Database 23ai 功能 (資料夾驅動程式或工具可能失敗)。
-
( 選擇性 ) 暴露於其他現代 SQL 方言 (PostgreSQL、MySQL 等等)。這將協助您欣賞
VALUES
、BOOLEAN
和IF EXISTS
等新功能的交叉相容性。
功能 1:使用 FROM
子句
Oracle Database 23ai 中引進的有趣功能是 SELECT
敘述句中 FROM
子句的選擇性功能。FROM
子句必須是最新版本。
以下是 SELECT
在 Oracle Database 23ai 中沒有 FROM
功能的一些潛在優勢。
-
選取目前日期以簡化資料處理。
SELECT CURRENT_DATE;
-
不涉及表格資料的數學運算或計算。
SELECT 25.50*25.25; 25.50*25.25 ----------- 643.875 Elapsed: 00:00:00.002 1 rows selected.
-
不使用
FROM
子句的 PL/SQL 區塊。CREATE SEQUENCE empno_seq INCREMENT BY 1 START WITH 1 MINVALUE 1 MAXVALUE 1000; Sequence EMPNO_SEQ created. Elapsed: 00:00:00.005 declare v1 number; begin select empno_seq.nextval into v1; dbms_output.put_line ('v1= '||v1); end; / v1= 1 PL/SQL procedure successfully completed. Elapsed: 00:00:00.009
-
內建或使用者定義的功能,可執行作業或擷取值。
SELECT DBMS_RANDOM.VALUE() as random_number;
-
不需依賴表格資料的字串操控或轉換。
SELECT UPPER('oracle') AS uppercase_text;
-
不使用表格的條件或邏輯表示式。
SELECT CASE WHEN 10 > 5 THEN 'True' ELSE 'False' END AS result;
功能 2:使用 BOOLEAN
資料類型
Oracle Database 23ai 推出了新的 BOOLEAN
資料類型。這會利用真布林值資料欄 / 變數,而不是使用數值或 Varchar 來模擬它們。編寫布林值述詞的功能可簡化 SQL 敘述句的語法。
-
建立一個名為
TEST_BOOLEAN
的表格。CREATE TABLE IF NOT EXISTS TEST_BOOLEAN (name VARCHAR2(100), IS_SLEEPING BOOLEAN); Table TEST_BOOLEAN created. Elapsed: 00:00:00.004
-
將資料輸入新表格。值
IS_SLEEPING
將設為NOT NULL
(預設值為FALSE
)。ALTER TABLE TEST_BOOLEAN modify (IS_SLEEPING boolean NOT NULL);
ALTER TABLE TEST_BOOLEAN modify (IS_SLEEPING default FALSE); Table TEST_BOOLEAN altered. Elapsed: 00:00:00.014
在這裡,您可以看到 Mick、Keith 和 Ron 的不同布林輸入類型。全部都有效。對於 Mick,會使用預設的 FALSE 值 - Mick 不會休眠。
1 row inserted. Elapsed: 00:00:00.006
對 Keith 而言,我們使用 NO 值 - Keith 不會睡覺。
INSERT INTO TEST_BOOLEAN (name, is_sleeping) values ('Keith','NO'); 1 row inserted. Elapsed: 00:00:00.002
對於 Ron 而言,我們使用 1 值 - Ron 正在睡覺。
-
根據我們的布林值查看一些結果。
SELECT * FROM test_boolean;
您不再需要記住您所放置的布林系統種類。如上所示,使用 0/1、True/False、Yes/No 或任何其他通用輸入將傳回準確的表格值。
功能 3:使用 IF NOT EXISTS
DDL 子句
從 Oracle Database 23ai 開始,您可以使用新的 IF NOT EXISTS
DDL 子句來決定如何處理 DDL 錯誤。這可簡化 DDL 命令檔處理,因為物件存在或不存在所造成的潛在錯誤可能會對命令檔隱藏。
-
首先,請不使用此新功能進行測試。執行下列陳述式。
DROP TABLE DEPT;
由於沒有現有的
DEPT
表格可供刪除,因此會看到錯誤:ORA-00942: table or view does not exist
。 -
不過,在 Oracle Database 23ai 中,我們可以在沒有錯誤的情況下使用
DROP IF EXISTS
。這讓我們在避免錯誤的同時放心。現在,執行相同的陳述式,但包括此新的IF EXISTS
功能。DROP TABLE IF EXISTS DEPT;
-
同樣地,如果表格不存在,我們可以使用此功能來建立表格。建立該
DEPT
表格。CREATE TABLE IF NOT EXISTS DEPT (DEPTNO NUMBER(2) CONSTRAINT PK_DEPT PRIMARY KEY, DNAME VARCHAR2(14) , LOC VARCHAR2(13) ) ;
-
使用此功能可在本教學課程中建立更多範例表格。在這裡,我們將建立一個名為
EMP
的員工表格。CREATE TABLE IF NOT EXISTS EMP (EMPNO NUMBER(4) CONSTRAINT PK_EMP PRIMARY KEY, ENAME VARCHAR2(10), JOB VARCHAR2(9), MGR NUMBER(4), HIREDATE DATE, SAL NUMBER(7,2), COMM NUMBER(7,2), DEPTNO NUMBER(2) CONSTRAINT FK_DEPTNO REFERENCES DEPT); Table EMP created. Elapsed: 00:00:00.006
功能 4:對多個資料列使用 INSERT
另一個有趣的功能是確保與其他常用資料庫管理系統保持更好的共存與相容性,這也是多值 INSERT
敘述句。
-
例如,在舊版的 Oracle 資料庫中,插入多個資料列時,每個資料列都需要一個個別的插入敘述句。
INSERT INTO DEPT VALUES (10,'ACCOUNTING','NEW YORK'); INSERT INTO DEPT VALUES (20,'RESEARCH','DALLAS'); INSERT INTO DEPT VALUES (30,'SALES','CHICAGO'); INSERT INTO DEPT VALUES (40,'OPERATIONS','BOSTON'); INSERT INTO DEPT VALUES (50,'HR','LOS ANGELES'); INSERT INTO DEPT VALUES (60,'IT','SAN FRANCISCO'); INSERT INTO DEPT VALUES (70,'MANUFACTURING','DETROIT');
Oracle Database 23ai 導入了新的語法,允許將所有這些資料列插入單一的
INSERT
敘述句中,因此您可以在一個 DML 中插入數個元組。執行下列陳述式。INSERT INTO DEPT VALUES (10,'ACCOUNTING','NEW YORK'), (20,'RESEARCH','DALLAS'), (30,'SALES','CHICAGO'), (40,'OPERATIONS','BOSTON'), (50,'HR','LOS ANGELES'), (60,'IT','SAN FRANCISCO'), (70,'MANUFACTURING','DETROIT');
除了與其他資料庫的較佳相容性之外,此敘述句還可用來確保某些插入作業在自動確認模式中的一致性。例如,對於使用此模式來處理資料的 Oracle APEX 應用程式而言,這可能很重要。
-
執行下列陳述式以使用此功能來填入
EMP
表格的值。INSERT INTO EMP VALUES (7369,'SMITH','CLERK',7902,to_date('17-12-1980','dd-mm-yyyy'),800,NULL,20), (7499,'ALLEN','SALESMAN',7698,to_date('20-2-1981','dd-mm-yyyy'),1600,300,30), (7521,'WARD','SALESMAN',7698,to_date('22-2-1981','dd-mm-yyyy'),1250,500,30), (7566,'JONES','MANAGER',7839,to_date('2-4-1981','dd-mm-yyyy'),2975,NULL,20), (7654,'MARTIN','SALESMAN',7698,to_date('28-9-1981','dd-mm-yyyy'),1250,1400,30), (7698,'BLAKE','MANAGER',7839,to_date('1-5-1981','dd-mm-yyyy'),2850,NULL,30), (7782,'CLARK','MANAGER',7839,to_date('9-6-1981','dd-mm-yyyy'),2450,NULL,10), (7788,'SCOTT','ANALYST',7566,to_date('13-JUL-87')-85,3000,NULL,20), (7839,'KING','PRESIDENT',NULL,to_date('17-11-1981','dd-mm-yyyy'),5000,NULL,10), (7844,'TURNER','SALESMAN',7698,to_date('8-9-1981','dd-mm-yyyy'),1500,0,30), (7876,'ADAMS','CLERK',7788,to_date('13-JUL-87')-51,1100,NULL,20), (7900,'JAMES','CLERK',7698,to_date('3-12-1981','dd-mm-yyyy'),950,NULL,30), (7902,'FORD','ANALYST',7566,to_date('3-12-1981','dd-mm-yyyy'),3000,NULL,20), (7934,'MILLER','CLERK',7782,to_date('23-1-1982','dd-mm-yyyy'),1300,NULL,10);
功能 5:使用新的 VALUE
建構子
從 Oracle 資料庫 23ai 開始,已經擴充表格值建構子。現在可以在 INSERT
敘述句中使用它,在單一命令中建立數個資料列。它也可以用於 SELECT
敘述句和檢視因子語法中。在最後一個案例中,它會簡化敘述句的語法,並避免使用 DUAL
表格。
下列陳述式看起來像是即時的表格函數。
SELECT * FROM (VALUES (50,'HR'), (60,'DEV'), (70,'AI')) virt_dept (deptno, dname);
功能 6:在 GROUP BY
子句中使用別名
Oracle Database 23ai 導入了在 SELECT
陳述式的 GROUP BY
子句中使用別名的功能。此功能可簡化使用複雜表示式的寫入查詢,並確保與一些其他關聯式資料庫 (例如 Teradata、MySQL 和 PostgreSQL) 的相容性。
舉例而言:
SELECT to_char(hiredate,'YYYY') "Year", count(*)
FROM emp
GROUP BY to_char(hiredate,'YYYY');
在 Oracle Database 23ai 中,可以較簡單的方式撰寫,如下圖所示:
功能 7:使用 UPDATE
和 MERGE
敘述句的 RETURNING
子句
先前已將此子句導入為 EXECUTE IMMEDIATE
敘述句的一部分。不過,在 Oracle Database 23ai 中,我們可以將它視為傳統靜態 DML 敘述句的一部分。
-
在此情況下,它允許從處理的資料列取得資料欄的舊值和新值。首先,讓我們看到國王目前的薪資。
SELECT ename, sal FROM emp WHERE ename = 'KING';
-
若要在 LiveSQL 中使用變數,我們將結束 PL/SQL 中的敘述句。執行此命令檔。它會先為舊薪資和新薪資建立變數,然後使用
RETURNING
子句更新 King 的薪資以設定變數。我們將檢視相關結果。BEGIN DECLARE old_salary NUMBER; new_salary NUMBER; BEGIN UPDATE emp SET sal = sal + 1000 WHERE ename = 'KING' RETURNING OLD sal, NEW sal INTO old_salary, new_salary; DBMS_OUTPUT.PUT_LINE('Old Salary: ' || old_salary); DBMS_OUTPUT.PUT_LINE('New Salary: ' || new_salary); END; END;
Old Salary: 6000 New Salary: 7000
此範例使用了
UPDATE
陳述式,但RETURNING
子句可以使用類似於MERGE
陳述式。
功能 8:在 UPDATE
和 DELETE
中使用結合
您可以根據外部表格條件使用結合來更新表格資料。不需要子選取項目或 IN
子句。
-
執行以下陳述式,以查看研究部門的員工薪資資訊。
select e.sal, e.empno from emp e, dept d where e.deptno=d.deptno and d.dname='RESEARCH';
-
若要更新薪資資訊,在 Oracle Database 23ai 之前,我們需要使用巢狀陳述式。
UPDATE emp e set e.sal=e.sal*2 WHERE e.deptno in (SELECT d.deptno FROM dept d WHERE e.deptno=d.deptno and d.dname='RESEARCH');
在 Oracle Database 23ai 中,您可以使用下列方式:
UPDATE emp e set e.sal=e.sal*2 FROM dept d WHERE e.deptno=d.deptno and d.dname='RESEARCH';
-
您可以查看已順利更新的薪資。
select e.sal, e.empno from emp e, dept d where e.deptno=d.deptno and d.dname='RESEARCH';
功能 9:使用註釋
註解是資料庫物件的選擇性描述資料。註解可以是名稱 - 值組或名稱本身。名稱和選擇性值為任意格式文字欄位。註解會以從屬元素表示至已新增註解的資料庫物件。支援的綱要物件包括表格、視觀表、具體化視觀表以及索引。您可以使用註解來儲存和擷取資料庫物件的相關描述資料。您可以使用它來自訂商業邏輯、使用者介面或提供描述資料給描述資料儲存區域。可以新增表格或資料欄層次的 CREATE
或 ALTER
敘述句。
您可以使用註解來儲存和擷取資料庫物件的相關描述資料。您可以使用它來自訂商業邏輯、使用者介面或提供描述資料給描述資料儲存區域。
-
建立含有資料欄和表格註解的加註表格
EMP_ANNOTATED_NEW
。CREATE TABLE emp_annotated_new (empno number annotations(identity, display 'person_identity', details 'person_info'), ename varchar2(50), salary number annotations (display 'person_salary', col_hidden)) annotations (display 'employee_table');
-
資料字典視觀表 (例如
USER_ANNOTATIONS
和USER_ANNOTATIONS_USAGE
) 可協助監督使用狀況。SELECT object_name, object_type, column_name, annotation_name, annotation_value FROM user_annotations_usage;
功能 10:使用 SQL 網域
SQL 網域是屬於綱要並封裝一組選擇性特性和限制條件的說明物件,並以 CREATE DOMAIN
敘述句建立。網域提供限制條件、顯示、排序以及註解屬性。定義 SQL 網域之後,您可以定義要與該網域關聯的表格資料欄,藉此明確地將網域的選擇性特性和限制套用至這些資料欄。
SQL 網域可讓使用者宣告資料欄的用途。它們是資料說明物件,因此可以輕鬆地重複使用抽象網域特定知識。
-
建立名為
yearbirth
的網域和名為person
的表格。CREATE DOMAIN yearbirth as number(4) constraint check ((trunc(yearbirth) = yearbirth) and (yearbirth >= 1900)) display (case when yearbirth < 2000 then '19-' ELSE '20-' end)||mod(yearbirth, 100) order (yearbirth -1900) annotations (title 'yearformat');
CREATE TABLE person (id number(5), name varchar2(50), salary number, person_birth number(4) DOMAIN yearbirth ) annotations (display 'person_table');
``` 描述;
Name Null?Type
ID 編號 (5) 名稱 VARCHAR2 (50) 薪資編號 PERSON_BIRTH 編號 (4) 領域 出生年份
INSERT INTO 人員值 (1,'MARTIN',3000,1988);
2. With the new function `DOMAIN_DISPLAY` you can display the property.
選擇 DOMAIN_DISPLAY (person_birth);

3. Domain usage and annotations can be monitored with data dictionary views. Let us view `user_annotations_usage`.
從 user_annotations_usage 選取 *;
Define reusable domain types (lightweight objects).
建立網域 EmailAddress 作為 VARCHAR2 (100) 檢查 (REGEXP_LIKE (值,'^[^@]+@[^@]+.[^@]+$'));
CREATE TABLE 使用者 (user_id NUMBER,email EmailAddress);```
Oracle Database 23ai 功能的限制與限制
-
FROM
子句。-
僅適用於簡單表示式,例如函數、文字或變數。
-
無法與表格、結合或子查詢有關的查詢搭配使用。
-
PL/SQL 相關資訊環境不支援具有預期為
FROM
子句之游標迴圈的游標。
-
-
原生
BOOLEAN
資料類型。-
可用於表格資料欄與表示式。
-
無法編製索引,無法編製
BOOLEAN
資料類型的資料欄索引。 -
並未在所有用戶端工具或報告工具中直接支援 (可能需要轉譯為 0/1 或 Y/N)。
-
部分較舊的 API 或驅動程式不支援 (JDBC/ODBC 從屬端可能需要更新)。
-
-
DDL 中的
IF NOT EXISTS
。-
簡化冪等 DDL 命令檔。
-
僅適用於特定物件:
TABLE
、INDEX
、SEQUENCE
、VIEW
等。 -
並非所有物件類型都支援此功能 (例如,
TRIGGER
、SYNONYM
可能仍需要手動檢查)。 -
舊版 Oracle 不支援此功能。
-
-
多重值
INSERT
。-
清除批次插入的語法。
-
限制為明確值集無法在相同的
VALUES
子句中使用SELECT
或子查詢插入。 -
無法在單一步驟中與所有插入資料列的
RETURNING
子句結合。
-
-
表格值建構子 (
VALUES
子句) 。-
適合小型的特設資料列集。
-
具有列限制 (通常為 999 或更少,視環境定義而定)。
-
未針對大規模負載進行最佳化,較適合用於大型資料集的暫時表格或暫存。
-
-
GROUP BY
子句中的別名。-
讓查詢更容易讀取和寫入。
-
並非所有涉及子查詢資料欄的分析函數或複雜查詢都支援。
-
別名超載的查詢可能會導致混淆 (例如,內部查詢中的名稱相同)。
-
-
UPDATE
/MERGE
中的RETURNING
子句。-
減少 DML 之後的
SELECT
需求。 -
只能從實際修改的資料列傳回值。
-
在沒有
FORALL
的情況下無法使用大量更新,必須使用具有明確RETURNING BULK COLLECT
的 PL/SQL。
-
-
UPDATE
和DELETE
中的結合。-
簡化多表格邏輯。
-
某些相關資訊環境中僅支援
INNER JOIN
和LEFT JOIN
類型。 -
如果使用較舊的工具或需要與較早的 Oracle 版本相容,則可能需要重新寫入
MERGE
邏輯。
-
-
註解。
-
適用於文件。
-
註釋僅為中繼資料,無法在執行時期強制執行。
-
需要使用 Oracle 資料說明視觀表 (
*_ANNOTATIONS
) 來擷取。 -
尚未整合至 Oracle Data Pump 匯出 / 匯入或複製工具。
-
-
具有 SQL 網域的輕量型物件類型。
-
可重複使用且一致的類型強制實行。
-
仍然比完整物件類型更強大 (沒有方法、屬性)。
-
沒有繼承或組成,只適用於原始限制強制實行。
-
無法在網域本身定義預設值 (仍然在資料欄層級指定預設值)。
-
一般限制
-
工具相容性:許多 GUI 工具和較舊的 Oracle 從屬端程式庫可能尚未完全支援 Oracle Database 23ai 語法 (特別是
VALUES
、BOOLEAN
、DOMAIN
)。 -
匯出 / 匯入:舊版
expdp
/impdp
工作流程中可能無法保留一些註解或網域等功能。 -
實驗性行為:由於這些功能是新的,部分功能可能會在次要版本中發展 — 請經常檢查修正程式注意事項和文件。
相關連結
確認
- 作者 - Aditya Srivastawa (首席雲端架構師)
其他學習資源
在 docs.oracle.com/learn 上探索其他實驗室,或在 Oracle Learning YouTube 頻道上存取更多免費學習內容。此外,請造訪 education.oracle.com/learning-explorer 以成為 Oracle Learning Explorer。
如需產品文件,請造訪 Oracle Help Center 。
Explore SQL Features in Oracle Database 23ai
G35703-01
Copyright ©2025, Oracle and/or its affiliates.