【Oracle 23ai】新機能・変更点完全ガイド|BOOLEAN型・IF EXISTS・GROUP BYエイリアス・SQL Domains・VECTORまで実例で解説

【Oracle 23ai】新機能・変更点完全ガイド|BOOLEAN型・IF EXISTS・GROUP BYエイリアス・SQL Domains・VECTORまで実例で解説 Oracle

Oracle 23ai(2024年リリース)は、長年の要望に応える数多くの新機能を搭載したメジャーアップデートです。前身の Oracle 23c Free(2023年リリース)で先行公開された機能が正式に採用され、さらに AI・機械学習との連携を強化した Oracle AI Features が追加されています。

本記事では開発者・DBAが特に注目すべき新機能を、実際に動作するSQLコードとともに解説します。

この記事でわかること

  • 待望の BOOLEAN データ型(Oracle史上初)
  • DDL の IF [NOT] EXISTS 構文(CREATE / DROP / ALTER)
  • GROUP BY でのカラムエイリアス使用
  • FROM DUAL の省略(SELECT without FROM)
  • SQL Domains(再利用可能なカラム制約定義)
  • Annotations(テーブル・カラムへのメタデータ付与)
  • VECTOR データ型(AI・機械学習向けベクトル検索)
  • スキーマレベルの権限付与
バージョン 正式名称 提供形態 リリース
Oracle 23c Free Oracle Database 23c Free 無償版(開発・学習用) 2023年
Oracle 23ai Oracle Database 23ai Enterprise / Standard 含む全エディション 2024年

「23ai」のネーミングは AI 機能の強化を象徴しており、従来の 23c から名称変更されました。既存の Oracle 19c(長期サポート版、サポート期限2027年)からの移行先として注目されています。

スポンサーリンク

BOOLEAN データ型(待望の正式サポート)

Oracle は長らく SQL レベルの BOOLEAN 型を持たず、NUMBER(1) や CHAR(1) で代用するのが慣行でした。Oracle 23ai でついにSQL の BOOLEAN データ型が正式サポートされました。(PL/SQL の BOOLEAN 型は以前から存在していましたが、SQL 列型としては使えませんでした。)

BOOLEAN 型の基本:テーブル定義と INSERT
-- Oracle 23ai: BOOLEAN 型が SQL 列として使用可能
CREATE TABLE products (
    product_id  NUMBER PRIMARY KEY,
    name        VARCHAR2(100),
    is_active   BOOLEAN DEFAULT TRUE,
    is_featured BOOLEAN DEFAULT FALSE
);

-- TRUE / FALSE / NULL を直接 INSERT できる
INSERT INTO products VALUES (1, 'Widget A', TRUE,  FALSE);
INSERT INTO products VALUES (2, 'Widget B', TRUE,  TRUE);
INSERT INTO products VALUES (3, 'Widget C', FALSE, FALSE);
INSERT INTO products VALUES (4, 'Widget D', TRUE,  NULL);  -- NULL も可
COMMIT;
BOOLEAN 型の SELECT・WHERE・TO_CHAR
-- WHERE 句でそのまま条件指定可能
SELECT product_id, name
FROM products
WHERE is_active;               -- WHERE is_active = TRUE と同義
-- 結果: id=1,2,4(is_active が TRUE のもの)

-- FALSE を指定
SELECT product_id, name
FROM products
WHERE NOT is_active;           -- is_active = FALSE

-- TO_CHAR で文字列変換('TRUE'/'FALSE'/'')
SELECT name,
       TO_CHAR(is_active)  AS active_str,   -- 'TRUE' or 'FALSE' or ''(NULL)
       TO_CHAR(is_featured) AS featured_str
FROM products;
BOOLEAN 型と既存コードの互換性
-- 数値・文字列からの変換
SELECT product_id,
       CASE WHEN is_active THEN 1 ELSE 0 END AS active_num,  -- 数値変換
       CASE WHEN is_active THEN 'Y' ELSE 'N' END AS active_char  -- 文字変換
FROM products;

-- 既存の NUMBER(1) / CHAR(1) データを BOOLEAN カラムに移行
ALTER TABLE legacy_table ADD is_active_bool BOOLEAN;
UPDATE legacy_table SET is_active_bool = (is_active_num = 1);  -- 0以外はTRUE

DDL の IF [NOT] EXISTS 構文

PostgreSQL や MySQL では標準的だった IF NOT EXISTS / IF EXISTS が、Oracle 23ai でついに使えるようになりました。スクリプトの冪等性(何度実行しても同じ結果になる性質)を保つ際に特に便利です。

CREATE IF NOT EXISTS:オブジェクトが存在しない場合のみ作成
-- Oracle 23ai 以前: テーブルが既に存在すると ORA-00955 でエラー
-- CREATE TABLE employees ( ... );

-- Oracle 23ai: IF NOT EXISTS で存在チェックを省略可能
CREATE TABLE IF NOT EXISTS employees (
    employee_id  NUMBER         PRIMARY KEY,
    last_name    VARCHAR2(100)  NOT NULL,
    hire_date    DATE           DEFAULT SYSDATE,
    is_active    BOOLEAN        DEFAULT TRUE
);
-- → 既に存在する場合はスキップ(エラーにならない)
-- → 存在しない場合は作成

CREATE INDEX IF NOT EXISTS idx_emp_name ON employees (last_name);
-- → インデックスが存在しない場合のみ作成

CREATE SEQUENCE IF NOT EXISTS emp_seq START WITH 1 INCREMENT BY 1;
DROP IF EXISTS:オブジェクトが存在する場合のみ削除
-- Oracle 23ai 以前: 存在しないテーブルを DROP すると ORA-00942
-- DROP TABLE temp_work;

-- Oracle 23ai: IF EXISTS で存在チェックを省略可能
DROP TABLE IF EXISTS temp_work;
-- → 存在しない場合はスキップ(エラーにならない)

DROP INDEX IF EXISTS idx_old_data;
DROP SEQUENCE IF EXISTS old_seq;
DROP VIEW IF EXISTS v_old_report;
スクリプトの冪等化パターン(デプロイスクリプトに活用)
-- 環境構築・マイグレーションスクリプトが何度実行しても安全になる

-- 旧来の書き方(BEGIN EXCEPTION WHEN OTHERS THEN NULL; END; が必要だった)
BEGIN
    EXECUTE IMMEDIATE 'DROP TABLE work_log';
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
CREATE TABLE work_log ( ... );

-- Oracle 23ai の書き方(シンプル)
DROP TABLE IF EXISTS work_log;
CREATE TABLE IF NOT EXISTS work_log (
    log_id   NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    log_dt   TIMESTAMP DEFAULT SYSTIMESTAMP,
    message  VARCHAR2(4000)
);

GROUP BY でのカラムエイリアス使用

SQL の評価順序の制約上、これまで SELECT 句で定義したエイリアスを GROUP BY 句で使用することはできませんでした。Oracle 23ai ではGROUP BY でエイリアスが使用可能になりました。

GROUP BY カラムエイリアスの使用例
-- Oracle 23ai 以前: GROUP BY に元の式を書く必要があった
SELECT TO_CHAR(order_date, 'YYYY-MM') AS order_month,
       SUM(amount) AS total
FROM orders
GROUP BY TO_CHAR(order_date, 'YYYY-MM');   -- 長い式を繰り返す必要があった

-- Oracle 23ai: エイリアスで GROUP BY できる
SELECT TO_CHAR(order_date, 'YYYY-MM') AS order_month,
       SUM(amount) AS total
FROM orders
GROUP BY order_month;   -- エイリアスをそのまま使用可能
複雑な式でエイリアスが特に効果的
-- CASE 式や複雑な関数の結果をエイリアスで GROUP BY
SELECT
    CASE
        WHEN salary < 300000  THEN '30万未満'
        WHEN salary < 500000  THEN '30〜50万'
        WHEN salary < 800000  THEN '50〜80万'
        ELSE '80万以上'
    END AS salary_range,
    COUNT(*) AS emp_count,
    AVG(salary) AS avg_salary
FROM employees
GROUP BY salary_range   -- CASE 式を繰り返さずに済む
ORDER BY MIN(salary);

FROM DUAL の省略(SELECT without FROM)

Oracle の DUAL 表は、SQL の構文要件を満たすための特殊なダミー表です。他の RDBMS では不要ですが、Oracle では SELECT sysdate FROM dual; のように必須でした。Oracle 23ai では FROM 句を省略できるようになりました。

FROM DUAL が不要になった例
-- Oracle 23ai 以前
SELECT SYSDATE FROM dual;
SELECT 1 + 1 FROM dual;
SELECT USER FROM dual;
SELECT SYS_GUID() FROM dual;

-- Oracle 23ai: FROM DUAL を省略可能
SELECT SYSDATE;
SELECT 1 + 1;
SELECT USER;
SELECT SYS_GUID();

-- 関数呼び出し
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS');
SELECT UPPER('hello world');
FROM DUAL は引き続き使用可能
FROM DUAL を省略できるようになりましたが、既存コードを書き換える必要はありません。FROM dual は Oracle 23ai でも引き続き動作します。新規コードでは省略でき、既存コードとの混在も問題ありません。

SQL Domains(再利用可能なカラム制約)

SQL Domain は、カラムの型・制約・デフォルト値・フォーマットをひとまとめにした再利用可能な定義です。同じ制約を複数のテーブルに繰り返し書く必要がなくなり、変更時の一元管理が可能になります。SQL標準(SQL:2003)に基づいた機能です。

SQL Domain の作成と使用
-- メールアドレス用 Domain の作成
CREATE DOMAIN email_domain AS VARCHAR2(320)
    DEFAULT NULL
    CONSTRAINT valid_email
        CHECK (REGEXP_LIKE(VALUE, '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'))
    ANNOTATIONS (description 'RFC準拠メールアドレス');

-- 電話番号用 Domain の作成
CREATE DOMAIN phone_domain AS VARCHAR2(20)
    CONSTRAINT valid_phone
        CHECK (REGEXP_LIKE(VALUE, '^[0-9\-\+\(\) ]+$'));

-- テーブル定義で Domain を使用
CREATE TABLE customers (
    customer_id  NUMBER         PRIMARY KEY,
    name         VARCHAR2(100)  NOT NULL,
    email        email_domain,    -- Domain を型として指定
    phone        phone_domain
);

-- メールアドレスの CHECK 制約は Domain 側で管理される
INSERT INTO customers VALUES (1, '山田太郎', 'yamada@example.com', '03-1234-5678');
-- → OK

INSERT INTO customers VALUES (2, '佐藤花子', 'not-an-email', '090-9876-5432');
-- → ORA-02290: チェック制約(VALID_EMAIL)に違反しました
Domain の確認・変更・削除
-- Domain 一覧の確認
SELECT domain_name, data_type, data_length, nullable
FROM user_domains
ORDER BY domain_name;

-- Domain を使用しているカラムの確認
SELECT table_name, column_name, domain_name
FROM user_tab_columns
WHERE domain_name IS NOT NULL;

-- Domain の制約を変更
ALTER DOMAIN email_domain
    ADD CONSTRAINT max_length CHECK (LENGTH(VALUE) <= 254);

-- Domain の削除(参照しているカラムがある場合は FORCE が必要)
DROP DOMAIN IF EXISTS email_domain;
-- DROP DOMAIN IF EXISTS email_domain FORCE;  -- 参照カラムも解除して削除

Annotations(テーブル・カラムへのメタデータ付与)

Annotations は、テーブルやカラムに任意のメタデータ(名前付きタグ)を付与する機能です。アプリケーションフレームワーク・ORMとの連携や、論理名(日本語カラム名)の管理に活用できます。

Annotations の定義と参照
-- テーブル・カラムに Annotation を付与
CREATE TABLE employees (
    employee_id  NUMBER        PRIMARY KEY
        ANNOTATIONS (display_name '社員ID', mandatory),
    last_name    VARCHAR2(50)  NOT NULL
        ANNOTATIONS (display_name '姓', searchable),
    first_name   VARCHAR2(50)
        ANNOTATIONS (display_name '名'),
    salary       NUMBER(10, 2)
        ANNOTATIONS (display_name '給与', sensitive)
) ANNOTATIONS (
    description '社員マスターテーブル',
    version     '1.0'
);

-- Annotation の確認(USER_ANNOTATIONS)
SELECT object_name, object_type, column_name,
       annotation_name, annotation_value
FROM user_annotations
WHERE object_name = 'EMPLOYEES'
ORDER BY column_name, annotation_name;

-- 結果例:
-- EMPLOYEES  TABLE   (null)       DESCRIPTION  社員マスターテーブル
-- EMPLOYEES  COLUMN  EMPLOYEE_ID  DISPLAY_NAME 社員ID
-- EMPLOYEES  COLUMN  EMPLOYEE_ID  MANDATORY    (null)
-- EMPLOYEES  COLUMN  LAST_NAME    DISPLAY_NAME 姓
-- EMPLOYEES  COLUMN  SALARY       SENSITIVE    (null)
Annotations の主な活用シーン

  • 日本語表示名の管理:アプリケーションのラベル表示をDBで一元管理
  • フレームワーク連携:ORM・BI ツールが Annotation を読み取り自動設定
  • セキュリティ分類sensitive タグで個人情報カラムを識別
  • マイグレーション管理versiondeprecated タグでスキーマ進化を追跡

VECTOR データ型(AI・機械学習向けベクトル検索)

Oracle 23ai の目玉機能のひとつが VECTOR データ型です。テキスト・画像・音声などを数値ベクトルに変換した埋め込み(Embedding)を格納し、類似度検索(近傍探索)をSQL で実行できます。Oracle AI Vector Search(旧称: Similarity Search)として提供されます。

VECTOR 型の基本:テーブル定義と操作
-- VECTOR(次元数, 型) で宣言
-- 型: FLOAT32(デフォルト)/ FLOAT64 / INT8
CREATE TABLE documents (
    doc_id     NUMBER PRIMARY KEY,
    title      VARCHAR2(500),
    content    CLOB,
    embedding  VECTOR(1536, FLOAT32)   -- OpenAI text-embedding-3-small は1536次元
);

-- ベクトルデータの INSERT(アプリ側で埋め込み生成後に格納)
INSERT INTO documents (doc_id, title, embedding)
VALUES (1, 'Oracle 23ai 入門',
        '[0.023, -0.045, 0.112, ...]'::VECTOR);   -- JSON配列形式で INSERT

-- TO_VECTOR 関数を使った変換
INSERT INTO documents (doc_id, title, embedding)
VALUES (2, 'PL/SQL 実践',
        TO_VECTOR('[0.087, -0.031, 0.094, ...]'));
コサイン類似度による近傍検索
-- 入力クエリのベクトルに最も近いドキュメントを検索
-- VECTOR_DISTANCE: ベクトル間の距離を計算する関数
--   COSINE(コサイン距離)/ EUCLIDEAN(ユークリッド距離)/ DOT(内積)/ MANHATTAN

-- 入力クエリの埋め込みを指定して類似ドキュメントをTOP-5で取得
SELECT doc_id, title,
       VECTOR_DISTANCE(embedding,
                       TO_VECTOR('[0.025, -0.042, 0.108, ...]'),
                       COSINE) AS similarity_distance
FROM documents
ORDER BY similarity_distance
FETCH FIRST 5 ROWS ONLY;
-- 距離が小さいほど類似度が高い

-- APPROX_NEAREST_NEIGHBOR ヒントで近似近傍探索(大量データで高速化)
SELECT /*+ VECTOR_INDEX(documents embedding_idx) */
       doc_id, title
FROM documents
ORDER BY VECTOR_DISTANCE(embedding,
                          TO_VECTOR('[0.025, -0.042, 0.108, ...]'),
                          COSINE)
FETCH APPROX FIRST 10 ROWS ONLY;
VECTOR インデックス(HNSW)の作成
-- HNSW(Hierarchical Navigable Small World)インデックス
-- 近似近傍探索の高速化に使用
CREATE VECTOR INDEX idx_doc_embedding
    ON documents (embedding)
    ORGANIZATION INMEMORY NEIGHBOR GRAPH
    DISTANCE COSINE
    WITH TARGET ACCURACY 95
    PARAMETERS (type HNSW, neighbors 32, efconstruction 200);
-- type: HNSW(デフォルト)または IVF(Inverted File)

-- IVF インデックス(メモリ節約型、大規模データ向け)
CREATE VECTOR INDEX idx_doc_ivf
    ON documents (embedding)
    ORGANIZATION NEIGHBOR PARTITIONS
    DISTANCE COSINE
    WITH TARGET ACCURACY 90
    PARAMETERS (type IVF, neighbor_partitions 256);

スキーマレベルの権限付与

これまでは同一スキーマ内の各テーブル・ビューに個別に権限を付与する必要がありましたが、Oracle 23ai ではスキーマ単位での一括権限付与が可能になりました。

スキーマレベル GRANT(Oracle 23ai)
-- Oracle 23ai 以前: テーブルごとに個別付与が必要
GRANT SELECT ON hr.employees   TO readonly_user;
GRANT SELECT ON hr.departments TO readonly_user;
GRANT SELECT ON hr.jobs        TO readonly_user;
-- ... スキーマ内の全テーブル分繰り返す

-- Oracle 23ai: スキーマ全体への一括付与
GRANT SELECT ANY TABLE ON SCHEMA hr TO readonly_user;

-- 複数の権限をスキーマ単位で付与
GRANT SELECT, INSERT, UPDATE ON SCHEMA app_schema TO app_user;

-- REVOKE も同様にスキーマ単位で可能
REVOKE SELECT ANY TABLE ON SCHEMA hr FROM readonly_user;
スキーマレベル権限の確認
-- 付与したスキーマレベル権限の確認
SELECT grantee, owner, privilege, admin_option
FROM dba_tab_privs
WHERE type = 'SCHEMA'
ORDER BY grantee, owner;

-- または USER_SCHEMA_PRIVS(自分が付与を受けた権限)
SELECT *
FROM user_schema_privs;

Oracle 23ai へのアップグレードを検討すべきポイント

機能 恩恵を受けやすいシナリオ
BOOLEAN 型 フラグ列が多いシステム(0/1 の NUMBER や Y/N の CHAR を整理できる)
IF [NOT] EXISTS デプロイスクリプト・マイグレーションを冪等化したい
GROUP BY エイリアス 複雑な CASE 式や日付変換を GROUP BY に使う頻度が高いクエリ
SQL Domains メールアドレス・電話番号・コード体系など共通制約が多いシステム
Annotations 多言語対応・BI/レポートとの連携・スキーマドキュメント管理
VECTOR 型 RAG(検索拡張生成)・意味的類似検索・レコメンドエンジンの構築
スキーマ権限 読み取り専用ユーザーや連携システムへの権限管理を簡素化

まとめ

Oracle 23ai は「SQL標準への準拠強化」と「AI機能との融合」が2大テーマのリリースです。BOOLEAN 型・IF EXISTS・GROUP BY エイリアスなどは開発者の日常的なコーディングを即座に改善し、SQL Domains・Annotations はスキーマ設計の品質向上に貢献します。

一方、VECTOR 型は AI/ML システムと Oracle DB を統合するための基盤機能として、今後のシステム設計に影響を与える可能性があります。

現在 Oracle 19c(長期サポート版)を使用している場合、次の長期サポート版は Oracle 23ai です。移行計画を立てる際は、本記事で紹介した新機能の活用可否も検討材料に加えてみてください。

Oracle の権限管理についてはユーザー作成と権限付与ガイドも参照ください。また、最新Oracle機能と組み合わせたストアドプロシージャ・ファンクションの設計も活用できます。