Oracle 23ai 不支持在 SQL 中直接声明并运行内联过程;仅支持 TABLE VALUES、SELECT AI 和云函数调用等声明式或代理式能力,PL/SQL 过程仍须显式创建编译后调用。

Oracle 23ai 并不支持在 SQL 中“直接声明并运行内联过程”——这是个常见误解。它支持的是 TABLE VALUES 构造器(表值构造函数)和 SELECT AI 这类声明式能力,但 PL/SQL 过程仍必须显式创建、编译后调用,不能像 JavaScript 的箭头函数那样 inline 声明。
为什么有人误以为能写内联过程?
混淆主要来自两个新特性:
-
TABLE VALUES允许在INSERT或FROM子句中直接写多行数据,形如VALUES (1,'A'), (2,'B'),看起来像“内联数据结构”,但不是过程 -
SELECT AI接受自然语言提示(如SELECT AI '找出所有已婚客户总数'),背后由DBMS_CLOUD_AI调用 LLM 生成并执行 SQL —— 这是“AI 代理执行”,不是用户写的内联 PL/SQL - 部分文档把“SQL 函数可调用云函数”(如
OCI Functions)误读为“内联过程”,实际仍是通过DBMS_CLOUD_FUNCTION包封装的远程调用,过程体不在数据库本地
真正能 inline 的只有函数表达式,且限制极严
Oracle 支持在 SQL 中调用的“内联”成分,仅限于:
- 标量子查询:如
(SELECT COUNT(*) FROM emp WHERE dept_id = d.id),但这是子查询,不是过程 - 内联视图(
WITH子句):可定义临时结果集,但不能包含 DML 或事务控制逻辑 - SQL 函数(非过程):如
TO_CHAR(SYSDATE, 'YYYY-MM-DD'),函数必须被预定义、确定性(或标记为DETERMINISTIC),且不能有副作用(比如改表、发邮件)
一旦涉及 INSERT/UPDATE/COMMIT 或异常处理,就必须退回到 PL/SQL 块或存储过程 —— SQL 引擎本身不执行过程逻辑。
PRAGMA INLINE 不等于“内联过程”,而是编译器指令
有人看到 PRAGMA INLINE(calc_bonus, 'YES') 就以为能 inline 过程调用,其实:
- 它只对**已存在的、独立声明的子程序**生效(比如包里的函数或过程),作用是告诉编译器“把调用点展开成函数体代码”,类似 C 的
inline关键字 - 它不能让一个未声明的过程突然出现在 SQL 语句中间;也不能用于匿名块里的局部过程(PL/SQL 局部过程本身就不能被 SQL 调用)
- 若过程含
COMMIT或DBMS_OUTPUT,即使加了 pragma,SQL 中仍无法调用 —— 因为违反 SQL 函数的纯度要求
真正容易被忽略的一点:所谓“23ai 支持内联”,本质是强化了 SQL 的**声明能力**(VALUES)、**AI 驱动能力**(SELECT AI)和**外部集成能力**(DBMS_CLOUD_FUNCTION),而不是放宽 PL/SQL 的执行边界。想在 SQL 里跑过程逻辑,目前仍得走存储过程 + 应用层协调的老路。


















