本章把 Oracle APEX 应用中的内部 PL/SQL 能力整理为外部系统可调用的 REST API。学习重点不是单独创建一个端点,而是把数据读取、数据变更、共享业务规则、JSON 处理、ORDS Handler、Oracle 26ai 的双重性视图,以及基于角色和 OAuth 的访问控制串成一条完整集成链路。

建议按“需求和场景 → REST 与 JSON 基础 → ORDS 模块规划 → 只读端点 → 写入端点和业务规则 → 分层包 → 26ai 简化 → 安全保护”的顺序阅读。每个小节都保留官方来源链接,并把截图映射到本地捕获路径。

14 暴露用于集成的 API#

本节对应官方主题“Exposing APIs for Integration”。中文学习稿把它放在“集成 API 学习路径”这条主线上理解:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。

阅读时重点跟踪这些对象和概念:REST、ORDS、JSON、PL/SQL、SQL、OAuth 2.0、SQL Developer Web。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14 暴露用于集成的 API”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST 安全、Roles、Privileges 与 OAuth Clients。
  • 操作:根据本节主题“14 暴露用于集成的 API”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.1 梳理 Action Items API 需求#

本节对应官方主题“Reviewing Action Items API Requirements”。中文学习稿把它放在“Action Items 集成示例”这条主线上理解:围绕 Action Items、Team Members 和负责人约束,理解外部系统为什么需要读写应用数据。

阅读时重点跟踪这些对象和概念:REST。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.1 梳理 Action Items API 需求”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop / RESTful Services / SQL Developer Web REST Designer。
  • 操作:根据本节主题“14.1 梳理 Action Items API 需求”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:围绕 Action Items、Team Members 和负责人约束,理解外部系统为什么需要读写应用数据。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.2 复习 REST API 基础#

本节对应官方主题“Reviewing REST API Basics”。中文学习稿把它放在“集成 API 学习路径”这条主线上理解:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。

阅读时重点跟踪这些对象和概念:REST、JSON、PL/SQL、SQL、JSON Relational Duality View。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.2 复习 REST API 基础”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.2 复习 REST API 基础”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.3 规划 ORDS 服务模块#

本节对应官方主题“Planning Your ORDS Service Module”。中文学习稿把它放在“ORDS 服务建模”这条主线上理解:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。

阅读时重点跟踪这些对象和概念:REST、ORDS、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.3 规划 ORDS 服务模块”,说明它解决的核心问题是ORDS 模块、URL template、HTTP 方法和 handler 的服务契约。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:请求 URL、HTTP 方法、输入参数、状态码和响应体都能被明确解释。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.3 规划 ORDS 服务模块”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.4 使用 SQL Developer Web REST Designer#

本节对应官方主题“Using SQL Developer Web REST Designer”。中文学习稿把它放在“集成 API 学习路径”这条主线上理解:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。

阅读时重点跟踪这些对象和概念:REST、ORDS、SQL、SQL Developer Web。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.4 使用 SQL Developer Web REST Designer”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.4 使用 SQL Developer Web REST Designer”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.5 创建并测试只读 API#

本节对应官方主题“Creating and Testing Read-Only APIs”。中文学习稿把它放在“端点测试”这条主线上理解:用 curl、jq 或 Postman 直接观察 HTTP 状态码、JSON 响应和鉴权结果,而不是只依赖页面行为。

阅读时重点跟踪这些对象和概念:REST、JSON、SQL、Postman、curl、jq。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.5 创建并测试只读 API”,说明它解决的核心问题是使用命令行或 API 客户端直接验证 REST 响应。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:可以用工具看到原始 HTTP 请求、响应 JSON 和错误状态。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.5 创建并测试只读 API”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:用 curl、jq 或 Postman 直接观察 HTTP 状态码、JSON 响应和鉴权结果,而不是只依赖页面行为。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.6 在 REST API 中执行业务逻辑#

本节对应官方主题“Enforcing Business Logic in REST APIs”。中文学习稿把它放在“业务规则复用”这条主线上理解:把页面和 REST API 共享的默认值、校验、错误消息和回滚语义集中在数据库包中,避免两套入口产生不一致。

阅读时重点跟踪这些对象和概念:REST、PL/SQL、SQL、Text Message。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.6 在 REST API 中执行业务逻辑”,说明它解决的核心问题是页面和 REST API 共享业务规则、错误消息和事务回滚。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一条非法数据无论来自页面还是 API,都会得到一致的校验失败。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.6 在 REST API 中执行业务逻辑”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把页面和 REST API 共享的默认值、校验、错误消息和回滚语义集中在数据库包中,避免两套入口产生不一致。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.7 完全控制 REST API 行为#

本节对应官方主题“Controlling REST API Behavior Completely”。中文学习稿把它放在“集成 API 学习路径”这条主线上理解:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。

阅读时重点跟踪这些对象和概念:REST、ORDS、JSON、PL/SQL、SQL、绑定变量。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.7 完全控制 REST API 行为”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.7 完全控制 REST API 行为”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.8 通过分层包提升模块化#

本节对应官方主题“Layering Packages for Modularity”。中文学习稿把它放在“集成 API 学习路径”这条主线上理解:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。

阅读时重点跟踪这些对象和概念:REST、ORDS、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.8 通过分层包提升模块化”,说明它解决的核心问题是ORDS 模块、URL template、HTTP 方法和 handler 的服务契约。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:请求 URL、HTTP 方法、输入参数、状态码和响应体都能被明确解释。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.8 通过分层包提升模块化”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.9 在 Oracle 26ai 中简化 REST API#

本节对应官方主题“Simplifying REST APIs in Oracle 26ai”。中文学习稿把它放在“Oracle 26ai 的 JSON 简化路径”这条主线上理解:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。

阅读时重点跟踪这些对象和概念:REST、ORDS、JSON、AutoREST、JSON Relational Duality View。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9 在 Oracle 26ai 中简化 REST API”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.9 在 Oracle 26ai 中简化 REST API”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.10 使用基于角色的访问控制保护 API#

本节对应官方主题“Securing APIs with Role-Based Access Control”。中文学习稿把它放在“安全与授权”这条主线上理解:确认只有被授权的外部系统可以调用服务,并把角色、权限、客户端凭据和 bearer token 的边界说清楚。

阅读时重点跟踪这些对象和概念:REST、ORDS、OAuth 2.0、bearer token。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.10 使用基于角色的访问控制保护 API”,说明它解决的核心问题是安全边界、授权范围和外部系统身份。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:未授权请求应被拒绝,授权请求应只能访问被允许的 REST 模块。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST 安全、Roles、Privileges 与 OAuth Clients。
  • 操作:根据本节主题“14.10 使用基于角色的访问控制保护 API”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:确认只有被授权的外部系统可以调用服务,并把角色、权限、客户端凭据和 bearer token 的边界说清楚。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.1.1 查看 Action Item Teams 示例#

本节对应官方主题“Exploring Action Item Teams Example”。中文学习稿把它放在“Action Items 集成示例”这条主线上理解:围绕 Action Items、Team Members 和负责人约束,理解外部系统为什么需要读写应用数据。

阅读时重点跟踪这些对象和概念:REST API、ORDS、JSON 与共享业务逻辑。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.1.1 查看 Action Item Teams 示例”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop / RESTful Services / SQL Developer Web REST Designer。
  • 操作:根据本节主题“14.1.1 查看 Action Item Teams 示例”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:围绕 Action Items、Team Members 和负责人约束,理解外部系统为什么需要读写应用数据。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-1 查看 Action Item Teams 示例:官方捕获图片 1
图 14-2 查看 Action Item Teams 示例:官方捕获图片 2

14.1.2 理解集成场景#

本节对应官方主题“Understanding the Integration Scenario”。中文学习稿把它放在“集成 API 学习路径”这条主线上理解:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。

阅读时重点跟踪这些对象和概念:REST。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.1.2 理解集成场景”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop / RESTful Services / SQL Developer Web REST Designer。
  • 操作:根据本节主题“14.1.2 理解集成场景”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-3 理解集成场景:官方捕获图片 1

14.2.1 复习 REST API 的 HTTP 方法#

本节对应官方主题“Reviewing HTTP Methods for REST APIs”。中文学习稿把它放在“集成 API 学习路径”这条主线上理解:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。

阅读时重点跟踪这些对象和概念:REST、JSON。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.2.1 复习 REST API 的 HTTP 方法”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.2.1 复习 REST API 的 HTTP 方法”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源表格 1:表格结构按源页面保留。

Method Business Entity Operation
POST Create a new entity
GET Read an entity collection or a specific entity
PUT Update an existing entity with a new version
DELETE Delete an entity

14.2.2 检查 JSON 语法#

本节对应官方主题“Inspecting JSON Syntax”。中文学习稿把它放在“JSON 数据处理”这条主线上理解:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。

阅读时重点跟踪这些对象和概念:REST、JSON、curl。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.2.2 检查 JSON 语法”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.2.2 检查 JSON 语法”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

{
  "name": "Georgia",
  "role": "LEAD",
  "user_id": 5,
  "active": true
}

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

{
  "user_id": 5,
  "role": "LEAD",
  "name": "Georgia",
  "active": true
}

源示例 3:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

["apple","banana","cherry"]

源示例 4:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

[
  { "name": "Georgia", "role": "LEAD",   "user_id": 5, "active": true},
  { "name": "Karl",    "role": "MEMBER", "user_id": 8, "active": true}
]

源表格 5:表格结构按源页面保留。

Type Textual Representation
String "some text"
Number 42 or 3.14 (no quotes)
Boolean true or false
Null null
Object {…}
Array […]

14.2.3 在 SQL 中构造 JSON#

本节对应官方主题“Constructing JSON in SQL”。中文学习稿把它放在“JSON 数据处理”这条主线上理解:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。

阅读时重点跟踪这些对象和概念:REST、JSON、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.2.3 在 SQL 中构造 JSON”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.2.3 在 SQL 中构造 JSON”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

select
json_object
(
          '_id'
value
 ai.id,
          ai.name,
          ai.status,
          'team'
value
 (select
json_arrayagg
(

json_object
(
                                     'team_member_id'
value
 tm.id,
                                     'name'
value
 s.name,
                                     'user_id'
value
 tm.user_id,
                                     'role'
value
 tm.role))
                          from action_item_team_members tm
                          join staff s
                            on tm.user_id = s.id
                         where tm.action_id = ai.id))
  from action_items ai

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

{
  "_id": 14,
  "name": "End of Year Party",
  "status: "OPEN",
  "team": [
    {
      "team_member_id": 23,
      "name": "David",
      "user_id": 4,
      "role": "MEMBER"
    },
    {
      "team_member_id": 24,
      "name": "Georgia",
      "user_id": 5,
      "role": "LEAD"
    },
    {
      "team_member_id": 25,
      "name": "Jane",
      "user_id": 13,
      "role": "MEMBER"
    }
  ]
}

源示例 3:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

select json_object(
          '_id' value ai.id,
          ai.name,
          ai.status,
          'team' value (select json_arrayagg(
                                  json_object(
                                     'team_member_id' value tm.id,
                                     'name'           value s.name,
                                     'user_id'        value tm.user_id,
                                     'role'           value tm.role)

order by tm.role, s.name
)
                          from action_item_team_members tm
                          join staff s
                            on tm.user_id = s.id
                         where tm.action_id = ai.id))
  from action_items ai

源示例 4:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

{
  "_id": 14,
  "name": "End of Year Party",
  "status": "OPEN",
  "team": [
    {
      "team_member_id": 24,
      "name": "Georgia",
      "user_id": 5,
      "role": "LEAD"
    },
    {
      "team_member_id": 23,
      "name": "David",
      "user_id": 4,
      "role": "MEMBER"
    },
    {
      "team_member_id": 25,
      "name": "Jane",
      "user_id": 13,
      "role": "MEMBER"
    }
  ]
}

14.2.4 在 PL/SQL 中处理 JSON#

本节对应官方主题“Working with JSON in PL/SQL”。中文学习稿把它放在“JSON 数据处理”这条主线上理解:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。

阅读时重点跟踪这些对象和概念:REST、JSON、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.2.4 在 PL/SQL 中处理 JSON”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.2.4 在 PL/SQL 中处理 JSON”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.3.1 选择 Schema Alias#

本节对应官方主题“Choosing a Schema Alias”。中文学习稿把它放在“集成 API 学习路径”这条主线上理解:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。

阅读时重点跟踪这些对象和概念:ORDS。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.3.1 选择 Schema Alias”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.3.1 选择 Schema Alias”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

https://example.com/ords/
cloudcompanion
/...

14.3.2 识别模块中的 URL Template#

本节对应官方主题“Identifying URL Templates in a Module”。中文学习稿把它放在“ORDS 服务建模”这条主线上理解:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。

阅读时重点跟踪这些对象和概念:ORDS。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.3.2 识别模块中的 URL Template”,说明它解决的核心问题是ORDS 模块、URL template、HTTP 方法和 handler 的服务契约。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:请求 URL、HTTP 方法、输入参数、状态码和响应体都能被明确解释。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.3.2 识别模块中的 URL Template”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

https://example.com/ords/cloudcompanion
/v0/actionitems

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

https://example.com/ords/cloudcompanion
/v0/actionitems/1234

14.3.3 选择用于读取数据的 GET Handler#

本节对应官方主题“Choosing GET Handlers to Read Data”。中文学习稿把它放在“ORDS 服务建模”这条主线上理解:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。

阅读时重点跟踪这些对象和概念:ORDS。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.3.3 选择用于读取数据的 GET Handler”,说明它解决的核心问题是ORDS 模块、URL template、HTTP 方法和 handler 的服务契约。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:请求 URL、HTTP 方法、输入参数、状态码和响应体都能被明确解释。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.3.3 选择用于读取数据的 GET Handler”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-4 选择用于读取数据的 GET Handler:官方捕获图片 1

14.3.4 为 GET Handler 创建视图#

本节对应官方主题“Creating a View for GET Handlers”。中文学习稿把它放在“ORDS 服务建模”这条主线上理解:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。

阅读时重点跟踪这些对象和概念:ORDS、JSON。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.3.4 为 GET Handler 创建视图”,说明它解决的核心问题是ORDS 模块、URL template、HTTP 方法和 handler 的服务契约。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:请求 URL、HTTP 方法、输入参数、状态码和响应体都能被明确解释。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.3.4 为 GET Handler 创建视图”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

create view action_items_with_team_jv as
select ai.id,
       ai.name,
       ai.status,
       (select json_arrayagg(
                 json_object(
                   'team_member_id' value tm.id,
                   'name'           value s.name,
                   'user_id'        value tm.user_id,
                   'role'           value tm.role
                 )
               )
          from action_item_team_members tm
          join staff s on tm.user_id = s.id
         where tm.action_id = ai.id
       ) as team
from action_items ai

14.4.1 进入 SQL Developer Web REST Designer#

本节对应官方主题“Accessing SQL Developer Web REST Designer”。中文学习稿把它放在“集成 API 学习路径”这条主线上理解:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。

阅读时重点跟踪这些对象和概念:REST、SQL、SQL Developer Web。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.4.1 进入 SQL Developer Web REST Designer”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.4.1 进入 SQL Developer Web REST Designer”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-5 进入 SQL Developer Web REST Designer:官方捕获图片 1
图 14-6 进入 SQL Developer Web REST Designer:官方捕获图片 2

14.4.2 浏览 ORDS 服务定义#

本节对应官方主题“Navigating ORDS Service Definitions”。中文学习稿把它放在“ORDS 服务建模”这条主线上理解:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。

阅读时重点跟踪这些对象和概念:REST、ORDS、SQL、SQL Developer Web。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.4.2 浏览 ORDS 服务定义”,说明它解决的核心问题是ORDS 模块、URL template、HTTP 方法和 handler 的服务契约。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:请求 URL、HTTP 方法、输入参数、状态码和响应体都能被明确解释。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.4.2 浏览 ORDS 服务定义”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-7 浏览 ORDS 服务定义:官方捕获图片 1
图 14-8 浏览 ORDS 服务定义:官方捕获图片 2
图 14-9 浏览 ORDS 服务定义:官方捕获图片 3
图 14-10 浏览 ORDS 服务定义:官方捕获图片 4

14.5.1 定义只读集合查询#

本节对应官方主题“Defining a Read-Only Collection Query”。中文学习稿把它放在“集成 API 学习路径”这条主线上理解:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。

阅读时重点跟踪这些对象和概念:ORDS、JSON、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.5.1 定义只读集合查询”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.5.1 定义只读集合查询”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-11 定义只读集合查询:官方捕获图片 1

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

select id as
"_id"
,
       name,
       status,
       team as
"{}team"

  from action_items_with_team_jv
order by name, id

14.5.2 使用 curl 或 Postman 测试 Handler#

本节对应官方主题“Testing Handler with curl or Postman”。中文学习稿把它放在“ORDS 服务建模”这条主线上理解:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。

阅读时重点跟踪这些对象和概念:REST、ORDS、JSON、Postman、curl、jq。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.5.2 使用 curl 或 Postman 测试 Handler”,说明它解决的核心问题是ORDS 模块、URL template、HTTP 方法和 handler 的服务契约。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:请求 URL、HTTP 方法、输入参数、状态码和响应体都能被明确解释。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.5.2 使用 curl 或 Postman 测试 Handler”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-12 使用 curl 或 Postman 测试 Handler:官方捕获图片 1
图 14-13 使用 curl 或 Postman 测试 Handler:官方捕获图片 2
图 14-14 使用 curl 或 Postman 测试 Handler:官方捕获图片 3

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

$
curl https://example.com/ords/cloudcompanion/v0/actionitems

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

$ curl https://example.com/ords/cloudcompanion/v0/actionitems
| jq

14.5.3 为集合查询端点加入过滤和分页#

本节对应官方主题“Filtering/Paging Collection Query Endpoints”。中文学习稿把它放在“端点测试”这条主线上理解:用 curl、jq 或 Postman 直接观察 HTTP 状态码、JSON 响应和鉴权结果,而不是只依赖页面行为。

阅读时重点跟踪这些对象和概念:ORDS、JSON、curl。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.5.3 为集合查询端点加入过滤和分页”,说明它解决的核心问题是ORDS 模块、URL template、HTTP 方法和 handler 的服务契约。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:请求 URL、HTTP 方法、输入参数、状态码和响应体都能被明确解释。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.5.3 为集合查询端点加入过滤和分页”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:用 curl、jq 或 Postman 直接观察 HTTP 状态码、JSON 响应和鉴权结果,而不是只依赖页面行为。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

$ curl https://example.com/⋯/v0/actionitems?q={"name":{"$like":"%Party%"}}

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

{
    "items": [
        {
            "_id": 14,
            "name": "End of Year Party",
            "status": "OPEN",
            "team": [
                {
                    "team_member_id": 23,
                    "name": "David",
                    "user_id": 4,
                    "role": "MEMBER"
                },
                {
                    "team_member_id": 24,
                    "name": "Georgia",
                    "user_id": 5,
                    "role": "LEAD"
                },
                {
                    "team_member_id": 25,
                    "name": "Jane",
                    "user_id": 13,
                    "role": "MEMBER"
                }
            ]
        }
    ],

    "hasMore": false,
    "limit": 25,
    "offset": 0,
    "count": 1,

    "links": [
      ⋰
    ]
}

源示例 3:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

{
       ⋮
    "hasMore": false,
    "limit": 25,
    "offset": 0,
    "count": 1,
       ⋮
}

源示例 4:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

$ curl https://example.com/⋯/v0/actionitems?
limit=10

源示例 5:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

$ curl https://example.com/⋯/v0/actionitems?
offset=10
&
limit=10

源示例 6:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

$ curl https://⋯/v0/actionitems?
limit=5
&
q={"name":{"$like":"Feature:%"}}

源示例 7:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

$ curl https://⋯/v0/actionitems?
offset=5
&
limit=5
&
q={"name":{"$like":"Feature:%"}}

14.5.4 配置集合单项 Handler#

本节对应官方主题“Configuring a Collection Item Handler”。中文学习稿把它放在“ORDS 服务建模”这条主线上理解:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。

阅读时重点跟踪这些对象和概念:ORDS、JSON、SQL、curl、jq。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.5.4 配置集合单项 Handler”,说明它解决的核心问题是ORDS 模块、URL template、HTTP 方法和 handler 的服务契约。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:请求 URL、HTTP 方法、输入参数、状态码和响应体都能被明确解释。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.5.4 配置集合单项 Handler”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-15 配置集合单项 Handler:官方捕获图片 1

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

select id as "_id",
       name,
       status,
       team as "{}team"
  from action_items_with_team_jv

where id = :id

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

$ curl https://example.com/ords/cloudcompanion
/v0/actionitems/14
 | jq
{
    "id": 14,
    "name": "End of Year Party",
    "status": "OPEN",
    "team": [
        {
            "team_member_id": 23,
            "name": "David",
            "user_id": 4,
            "role": "MEMBER"
        },
        {
            "team_member_id": 24,
            "name": "Georgia",
            "user_id": 5,
            "role": "LEAD"
        },
        {
            "team_member_id": 25,
            "name": "Jane",
            "user_id": 13,
            "role": "MEMBER"
        }
    ],
    "links": [
        {
            "rel": "collection",
            "href": "https://example.com/ords/cloudcompanion/v0/actionitems/"
        }
    ]
}

14.6.1 复查数据变更规则#

本节对应官方主题“Reviewing Rules for Data Changes”。中文学习稿把它放在“业务规则复用”这条主线上理解:把页面和 REST API 共享的默认值、校验、错误消息和回滚语义集中在数据库包中,避免两套入口产生不一致。

阅读时重点跟踪这些对象和概念:REST。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.6.1 复查数据变更规则”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop / RESTful Services / SQL Developer Web REST Designer。
  • 操作:根据本节主题“14.6.1 复查数据变更规则”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把页面和 REST API 共享的默认值、校验、错误消息和回滚语义集中在数据库包中,避免两套入口产生不一致。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.6.2 为错误定义 Text Message#

本节对应官方主题“Defining Text Messages for Errors”。中文学习稿把它放在“业务规则复用”这条主线上理解:把页面和 REST API 共享的默认值、校验、错误消息和回滚语义集中在数据库包中,避免两套入口产生不一致。

阅读时重点跟踪这些对象和概念:REST、PL/SQL、SQL、Text Message。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.6.2 为错误定义 Text Message”,说明它解决的核心问题是页面和 REST API 共享业务规则、错误消息和事务回滚。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一条非法数据无论来自页面还是 API,都会得到一致的校验失败。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.6.2 为错误定义 Text Message”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把页面和 REST API 共享的默认值、校验、错误消息和回滚语义集中在数据库包中,避免两套入口产生不一致。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-16 为错误定义 Text Message:官方捕获图片 1

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

&{TEAM_MEMBER_NOT_FOUND}.

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

l_message := apex_lang.get_message(
                p_name   => 'TEAM_MEMBER_NOT_FOUND',
                p_params => apex_t_varchar2('name',l_team_member.name));

14.6.3 在页面和 PL/SQL 中使用 Text Message#

本节对应官方主题“Using Text Messages in Pages and PL/SQL”。中文学习稿把它放在“业务规则复用”这条主线上理解:把页面和 REST API 共享的默认值、校验、错误消息和回滚语义集中在数据库包中,避免两套入口产生不一致。

阅读时重点跟踪这些对象和概念:REST、PL/SQL、SQL、Text Message。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.6.3 在页面和 PL/SQL 中使用 Text Message”,说明它解决的核心问题是页面和 REST API 共享业务规则、错误消息和事务回滚。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一条非法数据无论来自页面还是 API,都会得到一致的校验失败。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.6.3 在页面和 PL/SQL 中使用 Text Message”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把页面和 REST API 共享的默认值、校验、错误消息和回滚语义集中在数据库包中,避免两套入口产生不一致。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

&{TEAM_MAX_ONE_LEAD}.

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

&{TEAM_MAX_ONE_LEAD
name="
&P3_NAME.
"
}.

源示例 3:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

l_message := apex_lang.get_message(
                p_name   => 'TEAM_MEMBER_NOT_FOUND',
                p_params => apex_t_varchar2(
'name'
,l_team_member.name));

14.6.4 以统一方式处理错误#

本节对应官方主题“Handling Errors in a Common Way”。中文学习稿把它放在“业务规则复用”这条主线上理解:把页面和 REST API 共享的默认值、校验、错误消息和回滚语义集中在数据库包中,避免两套入口产生不一致。

阅读时重点跟踪这些对象和概念:REST。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.6.4 以统一方式处理错误”,说明它解决的核心问题是页面和 REST API 共享业务规则、错误消息和事务回滚。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一条非法数据无论来自页面还是 API,都会得到一致的校验失败。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop / RESTful Services / SQL Developer Web REST Designer。
  • 操作:根据本节主题“14.6.4 以统一方式处理错误”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把页面和 REST API 共享的默认值、校验、错误消息和回滚语义集中在数据库包中,避免两套入口产生不一致。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

package app_common is

    c_workspace constant varchar2(40) := 'COMPANION';
    c_app_id    constant number       := 1001;

    -----------------------------------------------------------
    --
Return error message with indicated key

    -----------------------------------------------------------
    function
error_message
(
        p_message_key in varchar2,
        p_params      in apex_t_varchar2 default null)
        return           varchar2;
    -----------------------------------------------------------
    --
Report error message with indicated behavior if non-null

    -----------------------------------------------------------
    procedure
report_if_error
(
        p_error_message in varchar2);
    -----------------------------------------------------------
    --
Report error message with indicated message key

    -----------------------------------------------------------
    procedure
report_error_key
(
        p_error_message_key in varchar2,
        p_params            in apex_t_varchar2 default null);
end app_common;

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

package body app_common is
    --------------------------------------------
    function is_apex_call
    return boolean
    is
    begin
        return apex_application.g_flow_id is not null;
    end is_apex_call;
    --------------------------------------------
    function error_message(
        p_message_key in varchar2,
        p_params      in apex_t_varchar2 default null)
        return           varchar2
    is
    begin
        apex_util.set_workspace(c_workspace);
        return apex_lang.get_message(
                p_name           => p_message_key,
                p_params         => p_params,
                p_application_id => c_app_id);
    end error_message;
    --------------------------------------------
    procedure report_if_error(
        p_error_message in varchar2)
    is
        l_error varchar2(4000);
    begin
        if p_error_message is not null then
            if is_apex_call then
                apex_error.add_error (
                    p_message          => p_error_message,
                    p_display_location => apex_error.c_on_error_page);
            else
                raise_application_error(-20001,p_error_message);
            end if;
        end if;
    end report_if_error;
    -----------------------------------------------
    procedure report_error_key(
        p_error_message_key in varchar2,
        p_params            in apex_t_varchar2 default null)
    is
    begin
        report_if_error(
            p_error_message => error_message(p_error_message_key,p_params));
    end report_error_key;
end app_common;

14.6.5 编写可复用业务规则#

本节对应官方主题“Coding Business Rules for Reuse”。中文学习稿把它放在“业务规则复用”这条主线上理解:把页面和 REST API 共享的默认值、校验、错误消息和回滚语义集中在数据库包中,避免两套入口产生不一致。

阅读时重点跟踪这些对象和概念:REST、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.6.5 编写可复用业务规则”,说明它解决的核心问题是页面和 REST API 共享业务规则、错误消息和事务回滚。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一条非法数据无论来自页面还是 API,都会得到一致的校验失败。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.6.5 编写可复用业务规则”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把页面和 REST API 共享的默认值、校验、错误消息和回滚语义集中在数据库包中,避免两套入口产生不一致。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

package action_items_common is
    -----------------------------------------------------------------------
    -- Return true if the action item with provide id exists
    -----------------------------------------------------------------------
    function action_exists(
        p_action_id in number)
    return boolean;
    -----------------------------------------------------------------------
    -- Ensure id passed in is null, or return error message
    -----------------------------------------------------------------------
    function ensure_null_id_for_new_action(
        p_id   in number)
        return    varchar2;
    -----------------------------------------------------------------------
    -- Ensure action item exists, or return error message
    -----------------------------------------------------------------------
    function ensure_action_exists(
        p_action_id in number)
    return varchar2;
    -----------------------------------------------------------------------
    -- Ensure action item has exactly one Lead, or return error message
    -----------------------------------------------------------------------
    function one_lead_per_action_team(
        p_action_id in number)
    return varchar2;
    -----------------------------------------------------------------------
    -- Ensure action item has no duplicate members, or return error message
    -----------------------------------------------------------------------
    function no_duplicate_team_members(
        p_action_id in number)
    return varchar2;
    -----------------------------------------------------------------------
    -- Ensure role value is legal, or return error message
    -----------------------------------------------------------------------
    function is_valid_role(
        p_role_value in varchar2)
        return          varchar2;
end action_items_common;

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

package body action_items_common is
    ------------------------------------------------------------
    -- Constant for error message keys
    ------------------------------------------------------------
    c_msg_team_must_have_lead   constant varchar2(25) := 'TEAM_MUST_HAVE_A_LEAD';
    c_msg_team_max_one_lead     constant varchar2(25) := 'TEAM_MAX_ONE_LEAD';
    c_msg_team_no_duplicates    constant varchar2(25) := 'TEAM_NO_DUPE_MEMBERS';
    c_msg_action_item_not_found constant varchar2(25) := 'ACTION_ITEM_NOT_FOUND';
    c_msg_illegal_role_value    constant varchar2(25) := 'INVALID_ROLE_TYPE';
    c_msg_no_id_for_new_action  constant varchar2(25) := 'ID_UNEXPECTED_FOR_INSERT';

    c_no_error                  constant varchar2(1)  := null;
    ------------------------------------
    function ensure_null_id_for_new_action(
        p_id   in number)
        return    varchar2
    is
    begin
        if p_id is not null then
            return app_common.error_message(c_msg_no_id_for_new_action);
        end if;
        return c_no_error;
    end ensure_null_id_for_new_action;
    ------------------------------------
    function ensure_action_exists(
        p_action_id in number)
    return varchar2
    is
    begin
        if not action_exists(p_action_id) then
            return app_common.error_message(c_msg_action_item_not_found,
                    apex_t_varchar2('id',p_action_id));
        end if;
        return c_no_error;
    end ensure_action_exists;
    ------------------------------------
    function action_exists(
        p_action_id in number)
    return boolean
    is
    begin
        for j in (select null
                    from action_items
                   where id = p_action_id)
        loop
            return true;
        end loop;
        return false;
    end action_exists;
    ------------------------------------
    function one_lead_per_action_team(
        p_action_id in number)
        return         varchar2
    is
        l_lead_count number;
    begin
        -- Ensure the action id still exists since it might
        -- have been deleted. If it exists, perform the check
        -- on the children rows.
        for j in (select id
                    from action_items
                   where id = p_action_id) loop
            select count(*)
            into l_lead_count
            from action_item_team_members
            where action_id = p_action_id
            and role = 'LEAD';
            if l_lead_count != 1 then
                return app_common.error_message(
                      case
                            when l_lead_count < 1
                            then c_msg_team_must_have_lead
                            else c_msg_team_max_one_lead
                        end);
            end if;
        end loop;
        return c_no_error;
    end;

    ------------------------------------
    function no_duplicate_team_members(
        p_action_id in number)
        return         varchar2
    is
    begin
        -- Ensure the action id still exists since it might
        -- have been deleted. If it exists, perform the check
        -- on the children rows.
        for j in (select id
                    from action_items
                   where id = p_action_id) loop
            for k in (select user_id, count(*)
                        from action_item_team_members
                       where action_id = p_action_id
                       group by user_id
                       having count(*) > 1
                       fetch first row only) loop
                return app_common.error_message(c_msg_team_no_duplicates);
                exit;
            end loop;
        end loop;
        return c_no_error;
    end;

    ------------------------------------
    function is_valid_role(
        p_role_value in varchar2)
        return          varchar2
    is
    begin
        if p_role_value not in ('MEMBER','LEAD') then
            return app_common.error_message(
                    c_msg_illegal_role_value,
                    apex_t_varchar2('value',p_role_value));
        end if;
        return c_no_error;
    end is_valid_role;
end action_items_common;

14.6.6 在 UI 中体验校验失败#

本节对应官方主题“Experiencing Validation Failure in UI”。中文学习稿把它放在“业务规则复用”这条主线上理解:把页面和 REST API 共享的默认值、校验、错误消息和回滚语义集中在数据库包中,避免两套入口产生不一致。

阅读时重点跟踪这些对象和概念:REST。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.6.6 在 UI 中体验校验失败”,说明它解决的核心问题是页面和 REST API 共享业务规则、错误消息和事务回滚。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一条非法数据无论来自页面还是 API,都会得到一致的校验失败。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop / RESTful Services / SQL Developer Web REST Designer。
  • 操作:根据本节主题“14.6.6 在 UI 中体验校验失败”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把页面和 REST API 共享的默认值、校验、错误消息和回滚语义集中在数据库包中,避免两套入口产生不一致。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-17 在 UI 中体验校验失败:官方捕获图片 1

14.6.7 在 REST API 中接收校验错误#

本节对应官方主题“Receiving Validation Error in REST API”。中文学习稿把它放在“业务规则复用”这条主线上理解:把页面和 REST API 共享的默认值、校验、错误消息和回滚语义集中在数据库包中,避免两套入口产生不一致。

阅读时重点跟踪这些对象和概念:REST、ORDS、JSON、Postman、curl。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.6.7 在 REST API 中接收校验错误”,说明它解决的核心问题是页面和 REST API 共享业务规则、错误消息和事务回滚。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一条非法数据无论来自页面还是 API,都会得到一致的校验失败。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.6.7 在 REST API 中接收校验错误”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把页面和 REST API 共享的默认值、校验、错误消息和回滚语义集中在数据库包中,避免两套入口产生不一致。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-18 在 REST API 中接收校验错误:官方捕获图片 1

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

https://example.com/ords/cloudcompanion/v1/actionitems

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

{
  "name": "Website Redesign Project",
  "team": [
     {"role":"
LEAD
",  "name":"Levi"},
     {"role":"
LEAD
",  "name":"Opal"},
     {"role":"MEMBER","name":"David"},
     {"role":"MEMBER","name":"Georgia"},
  ]
}

源示例 3:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

{"$error":"Only one lead per action team"} 

14.7.1 提供完整的 ORDS Handler 集合#

本节对应官方主题“Providing Complete Set of ORDS Handlers”。中文学习稿把它放在“ORDS 服务建模”这条主线上理解:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。

阅读时重点跟踪这些对象和概念:REST、ORDS。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.7.1 提供完整的 ORDS Handler 集合”,说明它解决的核心问题是ORDS 模块、URL template、HTTP 方法和 handler 的服务契约。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:请求 URL、HTTP 方法、输入参数、状态码和响应体都能被明确解释。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.7.1 提供完整的 ORDS Handler 集合”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-19 提供完整的 ORDS Handler 集合:官方捕获图片 1

14.7.2 使用 Handler 绑定变量#

本节对应官方主题“Using Handler Bind Variables”。中文学习稿把它放在“ORDS 服务建模”这条主线上理解:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。

阅读时重点跟踪这些对象和概念:REST、PL/SQL、SQL、绑定变量。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.7.2 使用 Handler 绑定变量”,说明它解决的核心问题是ORDS 模块、URL template、HTTP 方法和 handler 的服务契约。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:请求 URL、HTTP 方法、输入参数、状态码和响应体都能被明确解释。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.7.2 使用 Handler 绑定变量”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.7.3 保持 PL/SQL Handler 可维护#

本节对应官方主题“Keeping PL/SQL Handlers Maintainable”。中文学习稿把它放在“ORDS 服务建模”这条主线上理解:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。

阅读时重点跟踪这些对象和概念:REST、ORDS、JSON、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.7.3 保持 PL/SQL Handler 可维护”,说明它解决的核心问题是ORDS 模块、URL template、HTTP 方法和 handler 的服务契约。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:请求 URL、HTTP 方法、输入参数、状态码和响应体都能被明确解释。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.7.3 保持 PL/SQL Handler 可维护”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-20 保持 PL/SQL Handler 可维护:官方捕获图片 1

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

begin

action_items_api_rest.update_object
(:id,:body_text,:debug);
end;

14.7.4 定义显式 Handler 参数#

本节对应官方主题“Defining Explicit Handler Parameters”。中文学习稿把它放在“ORDS 服务建模”这条主线上理解:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。

阅读时重点跟踪这些对象和概念:REST、ORDS、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.7.4 定义显式 Handler 参数”,说明它解决的核心问题是ORDS 模块、URL template、HTTP 方法和 handler 的服务契约。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:请求 URL、HTTP 方法、输入参数、状态码和响应体都能被明确解释。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.7.4 定义显式 Handler 参数”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-21 定义显式 Handler 参数:官方捕获图片 1

14.7.5 复用通用 REST API Handler 代码#

本节对应官方主题“Reusing Common REST API Handler Code”。中文学习稿把它放在“ORDS 服务建模”这条主线上理解:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。

阅读时重点跟踪这些对象和概念:REST、JSON、PL/SQL、SQL、绑定变量。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.7.5 复用通用 REST API Handler 代码”,说明它解决的核心问题是ORDS 模块、URL template、HTTP 方法和 handler 的服务契约。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:请求 URL、HTTP 方法、输入参数、状态码和响应体都能被明确解释。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.7.5 复用通用 REST API Handler 代码”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

package app_common_rest as
    --------------------------------------------------------------
    -- Set debug mode for error reporting
    --------------------------------------------------------------
    procedure set_debug(
        p_value in varchar2);
    --------------------------------------------------------------
    -- Commit and write out JSON response
    --------------------------------------------------------------
    procedure commit_and_send_response(
        p_json json_element_t default null);
    --------------------------------------------------------------
    -- Handle error by sending HTTP error with $error payload
    --------------------------------------------------------------
    procedure handle_error(
        p_error_message   in varchar2,
        p_http_error_code in number default 400);
end app_common_rest;

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

create or replace package body app_common_rest as
    g_debug_mode boolean := false;
    ------------------------------------
    procedure set_debug(
        p_value in varchar2)
    is
    begin
        if upper(p_value) = 'TRUE' then
            g_debug_mode := true;
        end if;
    end set_debug;
    ------------------------------------
    procedure commit_and_send_response(
        p_json in json_element_t default null)
    is
        l_has_json boolean := p_json is not null;
    begin
        commit;
        owa_util.mime_header('application/json', l_has_json);
        if p_json is not null then
            htp.p(p_json.stringify);
        else
            owa_util.status_line(204, 'No content', true);
        end if;
    end;
    --------------------------------------------------------------
    -- Handle error by sending HTTP 400 with $error payload
    --------------------------------------------------------------
    procedure handle_error(
        p_error_message   in varchar2,
        p_http_error_code in number default 400)
    is
        l_json_err json_object_t := json_object_t();
        l_json_arr json_array_t;
    begin
        owa_util.mime_header('application/json', p_error_message is null);
        owa_util.status_line(p_http_error_code, 'Error', true);
        if p_error_message is not null then
            l_json_err.put('$error',
                           regexp_replace(p_error_message,'^ORA-[0-9]+:\s'));
            if g_debug_mode then
                l_json_arr := json_array_t();
                for j in (select rownum, column_value
                            from table(apex_string.split(
                                dbms_utility.format_error_stack()
                                || chr(10)
                                || dbms_utility.format_error_backtrace())))
                loop
                    if j.column_value is not null then
                        l_json_arr.append(j.column_value);
                    end if;
                end loop;
                l_json_err.put('debug$error', l_json_arr);
            end if;
            htp.p(l_json_err.stringify);
        end if;
        rollback;
    end;
end app_common_rest;

14.7.6 读写二进制内容#

本节对应官方主题“Reading and Writing Binary Content”。中文学习稿把它放在“集成 API 学习路径”这条主线上理解:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。

阅读时重点跟踪这些对象和概念:REST、ORDS、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.7.6 读写二进制内容”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.7.6 读写二进制内容”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

select mime_type, file_contents
  from attachments
 where id = :id

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

begin

your_package
.insert_attachment(
       p_mime_type     =>
:content_type
,
       p_file_contents =>
:body
);
   commit;
end;

14.8.1 研究 API Handler 包分层#

本节对应官方主题“Studying API Handler Package Layers”。中文学习稿把它放在“ORDS 服务建模”这条主线上理解:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。

阅读时重点跟踪这些对象和概念:REST、ORDS、JSON、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.8.1 研究 API Handler 包分层”,说明它解决的核心问题是ORDS 模块、URL template、HTTP 方法和 handler 的服务契约。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:请求 URL、HTTP 方法、输入参数、状态码和响应体都能被明确解释。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.8.1 研究 API Handler 包分层”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-22 研究 API Handler 包分层:官方捕获图片 1
图 14-23 研究 API Handler 包分层:官方捕获图片 2

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

package action_items_api_rest as
    ------------------------------------
    procedure get_objects(
        p_search in varchar2,
        p_offset in number   default 0,
        p_limit  in number   default 10,
        p_debug  in varchar2 default null);
    ------------------------------------
    procedure get_object(
        p_id in number,
        p_debug  in varchar2 default null);
    ------------------------------------
    procedure insert_object(
        p_object in clob,
        p_debug  in varchar2 default null);
    ------------------------------------
    procedure update_object(
        p_id     in number,
        p_object in clob,
        p_debug  in varchar2 default null);
    ------------------------------------
    procedure delete_object(
        p_id     in number,
        p_debug  in varchar2 default null);
end action_items_api_rest;

14.8.2 检查核心 Action Item API 逻辑#

本节对应官方主题“Examining Core Action Item API Logic”。中文学习稿把它放在“Action Items 集成示例”这条主线上理解:围绕 Action Items、Team Members 和负责人约束,理解外部系统为什么需要读写应用数据。

阅读时重点跟踪这些对象和概念:REST、ORDS、JSON、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.8.2 检查核心 Action Item API 逻辑”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.8.2 检查核心 Action Item API 逻辑”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:围绕 Action Items、Team Members 和负责人约束,理解外部系统为什么需要读写应用数据。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.9.1 使用 JSON 类型和双重性视图#

本节对应官方主题“Using JSON Type and Duality Views”。中文学习稿把它放在“Oracle 26ai 的 JSON 简化路径”这条主线上理解:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。

阅读时重点跟踪这些对象和概念:REST、JSON、PL/SQL、SQL、ETAG、JSON Relational Duality View。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.1 使用 JSON 类型和双重性视图”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.9.1 使用 JSON 类型和双重性视图”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.9.2 探索双重性视图的 ORDS AutoREST#

本节对应官方主题“Exploring ORDS AutoREST for Duality View”。中文学习稿把它放在“Oracle 26ai 的 JSON 简化路径”这条主线上理解:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。

阅读时重点跟踪这些对象和概念:REST、ORDS、JSON、PL/SQL、SQL、AutoREST、SQL Developer Web、JSON Relational Duality View。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.2 探索双重性视图的 ORDS AutoREST”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.9.2 探索双重性视图的 ORDS AutoREST”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.9.3 配置 26ai API 的 ORDS Handler#

本节对应官方主题“Configuring ORDS Handlers for 26ai API”。中文学习稿把它放在“Oracle 26ai 的 JSON 简化路径”这条主线上理解:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。

阅读时重点跟踪这些对象和概念:REST、ORDS、JSON、JSON Relational Duality View。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.3 配置 26ai API 的 ORDS Handler”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.9.3 配置 26ai API 的 ORDS Handler”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-24 配置 26ai API 的 ORDS Handler:官方捕获图片 1
图 14-25 配置 26ai API 的 ORDS Handler:官方捕获图片 2
图 14-26 配置 26ai API 的 ORDS Handler:官方捕获图片 3

14.9.4 理解双重性视图如何简化逻辑#

本节对应官方主题“Seeing How Duality View Simplifies Logic”。中文学习稿把它放在“Oracle 26ai 的 JSON 简化路径”这条主线上理解:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。

阅读时重点跟踪这些对象和概念:REST、JSON、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.4 理解双重性视图如何简化逻辑”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.9.4 理解双重性视图如何简化逻辑”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.10.1 定义 ORDS 角色和权限#

本节对应官方主题“Defining ORDS Role and Privileges”。中文学习稿把它放在“安全与授权”这条主线上理解:确认只有被授权的外部系统可以调用服务,并把角色、权限、客户端凭据和 bearer token 的边界说清楚。

阅读时重点跟踪这些对象和概念:REST、ORDS、SQL、SQL Developer Web。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.10.1 定义 ORDS 角色和权限”,说明它解决的核心问题是安全边界、授权范围和外部系统身份。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:未授权请求应被拒绝,授权请求应只能访问被允许的 REST 模块。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.10.1 定义 ORDS 角色和权限”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:确认只有被授权的外部系统可以调用服务,并把角色、权限、客户端凭据和 bearer token 的边界说清楚。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-27 定义 ORDS 角色和权限:官方捕获图片 1
图 14-28 定义 ORDS 角色和权限:官方捕获图片 2

14.10.2 发放用于认证的 OAuth Client#

本节对应官方主题“Issuing OAuth Client for Authentication”。中文学习稿把它放在“安全与授权”这条主线上理解:确认只有被授权的外部系统可以调用服务,并把角色、权限、客户端凭据和 bearer token 的边界说清楚。

阅读时重点跟踪这些对象和概念:REST、ORDS、SQL、OAuth 2.0、SQL Developer Web、bearer token。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.10.2 发放用于认证的 OAuth Client”,说明它解决的核心问题是安全边界、授权范围和外部系统身份。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:未授权请求应被拒绝,授权请求应只能访问被允许的 REST 模块。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST 安全、Roles、Privileges 与 OAuth Clients。
  • 操作:根据本节主题“14.10.2 发放用于认证的 OAuth Client”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:确认只有被授权的外部系统可以调用服务,并把角色、权限、客户端凭据和 bearer token 的边界说清楚。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-29 发放用于认证的 OAuth Client:官方捕获图片 1
图 14-30 发放用于认证的 OAuth Client:官方捕获图片 2

14.10.3 使用 OAuth Client 调用 REST API#

本节对应官方主题“Using REST API with an OAuth Client”。中文学习稿把它放在“安全与授权”这条主线上理解:确认只有被授权的外部系统可以调用服务,并把角色、权限、客户端凭据和 bearer token 的边界说清楚。

阅读时重点跟踪这些对象和概念:REST、ORDS、JSON、OAuth 2.0、bearer token、curl。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.10.3 使用 OAuth Client 调用 REST API”,说明它解决的核心问题是安全边界、授权范围和外部系统身份。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:未授权请求应被拒绝,授权请求应只能访问被允许的 REST 模块。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST 安全、Roles、Privileges 与 OAuth Clients。
  • 操作:根据本节主题“14.10.3 使用 OAuth Client 调用 REST API”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:确认只有被授权的外部系统可以调用服务,并把角色、权限、客户端凭据和 bearer token 的边界说清楚。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

$ curl --user "QvUVx6Gp8P02dTb0C-II1A..:szUul--kEJ1Te-kS454_tQ.." \
--data "grant_type=client_credentials" \
https://example.com/ords/cloudcompanion
/oauth/token


{"
access_token
":"
SNVDe2Tjough44I_X6tmXg
","token_type":"bearer","expires_in":3600}

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

$ curl -H "Authorization: Bearer SNVDe2Tjough44I_X6tmXg"  \
https://example.com/ords/cloudcompanion/v1/actionitems/14

源示例 3:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

{
    "code": "Unauthorized",
    "message": "Unauthorized",
    "type": "tag:oracle.com,2020:error/Unauthorized",
    "instance": "tag:oracle.com,2020:ecid/636fea296204b162106f0cdb5d7e22bc"
}

14.2.4.1 在 PL/SQL 中解析 JSON#

本节对应官方主题“Parsing JSON in PL/SQL”。中文学习稿把它放在“JSON 数据处理”这条主线上理解:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。

阅读时重点跟踪这些对象和概念:JSON、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.2.4.1 在 PL/SQL 中解析 JSON”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.2.4.1 在 PL/SQL 中解析 JSON”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

declare
    l_actionitem json_object_t;
    l_team       json_array_t;
    l_member     json_object_t;
    -----------------------------
    function get_object(
        p_array in json_array_t,
        p_index in pls_integer)
        return     json_object_t
    is
    begin
        return treat(p_array.get(p_index) as json_object_t);
    end get_object;
begin
   l_actionitem := json_object_t(q'~
                    {
                      "name": "Practice Using JSON in PL/SQL",
                      "team": [
                        {"role": "LEAD","name": "Georgia"},
                        {"name": "Usha","role": "MEMBER"}
                      ]
                    }
                    ~');
   l_team   := l_actionitem.get_array('team');
   l_member := treat(l_team.get(0) as json_object_t);
   -- All three print out "Georgia"
   dbms_output.put_line(l_member.get_string('name'));
   dbms_output.put_line(treat(l_team.get(0) as json_object_t).get_string('name'));
   dbms_output.put_line(get_object(l_team,0).get_string('name'));
end;

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

ORA-30625: method dispatch on NULL SELF argument is disallowed

14.2.4.2 更具体地处理 JSON 元素#

本节对应官方主题“Treating an Element More Specifically”。中文学习稿把它放在“集成 API 学习路径”这条主线上理解:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。

阅读时重点跟踪这些对象和概念:JSON、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.2.4.2 更具体地处理 JSON 元素”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.2.4.2 更具体地处理 JSON 元素”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

JSON_ELEMENT_T
├── JSON_SCALAR_T
│   ├── JSON_NUMBER_T
│   ├── JSON_STRING_T
│   └── JSON_BOOLEAN_T
├── JSON_OBJECT_T
└── JSON_ARRAY_T

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

TREAT(… AS JSON_
SPECIFIC_TYPE
)

源示例 3:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- Get object with index p_index in an array of objects
function get_object(
    p_array in json_array_t,
    p_index in pls_integer)
    return     json_object_t
is
begin
    return treat(p_array.get(p_index) as json_object_t);
end get_object;

14.2.4.3 在 PL/SQL 中构造 JSON#

本节对应官方主题“Constructing JSON in PL/SQL”。中文学习稿把它放在“JSON 数据处理”这条主线上理解:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。

阅读时重点跟踪这些对象和概念:JSON、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.2.4.3 在 PL/SQL 中构造 JSON”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.2.4.3 在 PL/SQL 中构造 JSON”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

declare
    l_actionitem     json_object_t := json_object_t();
    l_team           json_array_t  := json_array_t();
    l_member_usha    json_object_t;
    l_member_georgia json_object_t;
begin
   l_actionitem.put('name', 'Practice Using JSON in PL/SQL');
   l_member_georgia := json_object_t();
   l_member_georgia.put('role', 'LEAD');
   l_member_georgia.put('name', 'Georgia');
   l_team.append(l_member_georgia);
   l_member_usha := json_object_t();
   l_member_usha.put('name', 'Usha');
   l_member_usha.put('role', 'MEMBER');
   l_team.append(l_member_usha);
   -- append all array elements before adding array to object
   l_actionitem.put('team', l_team);
   -- Both print out "Georgia"
   dbms_output.put_line(l_member_georgia.get_string('name'));
   dbms_output.put_line(treat(l_team.get(0) as json_object_t).get_string('name'));
end;

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

ORA-30625: method dispatch on NULL SELF argument is disallowed

14.2.4.4 在 PL/SQL 中序列化 JSON#

本节对应官方主题“Serializing JSON in PL/SQL”。中文学习稿把它放在“JSON 数据处理”这条主线上理解:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。

阅读时重点跟踪这些对象和概念:JSON、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.2.4.4 在 PL/SQL 中序列化 JSON”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.2.4.4 在 PL/SQL 中序列化 JSON”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

declare
    l_value varchar2(32767) := lpad('y',32767,'x');
    l_json  json_object_t   := json_object_t();
    -------------------------------------------------------
    procedure p(p_clob in clob)
    is
        l_offset integer := 1;
        l_chunk  varchar2(32767);
    begin
        while l_offset <= dbms_lob.getlength(p_clob) loop
        l_chunk := dbms_lob.substr(p_clob, 32767, l_offset);
        dbms_output.put_line(l_chunk);
        l_offset := l_offset + 32767;
        end loop;
    end p;
begin
  l_json.put('name',l_value);
  -- Gives ORA-40478: output value too large
  -- p(l_json.stringify);
  p(l_json.to_clob);
end;

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

ORA-30625: method dispatch on NULL SELF argument is disallowed

14.8.2.1 构造或查询 Action Item#

本节对应官方主题“Constructing or Querying an Action Item”。中文学习稿把它放在“Action Items 集成示例”这条主线上理解:围绕 Action Items、Team Members 和负责人约束,理解外部系统为什么需要读写应用数据。

阅读时重点跟踪这些对象和概念:JSON、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.8.2.1 构造或查询 Action Item”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.8.2.1 构造或查询 Action Item”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:围绕 Action Items、Team Members 和负责人约束,理解外部系统为什么需要读写应用数据。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- in package action_items_api
function get_object(
    p_id in number)
return json_object_t
is
    c_get_object_approach constant t_get_object_approach := c_approach_sql;
    l_ret json_object_t;
begin
    case c_get_object_approach
        when c_approach_programmatic then
            l_ret := get_object_programmatically(p_id);
        when c_approach_sql then
            l_ret := json_object_t(get_object_using_sql(p_id));
    end case;
    return l_ret;
end;

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- in package action_items_api
function get_object_programmatically(
    p_id in number)
return json_object_t
is
    l_action_item_rec action_items%rowtype;
    l_action_item_obj json_object_t := json_object_t();
    l_team_members_arr json_array_t := json_array_t();
    l_team_members     t_action_item_team_members := t_action_item_team_members();
    l_team_member_obj  json_object_t;
    l_team_member_name staff.name%type;
begin
    app_common.report_if_error(
        action_items_common.ensure_action_exists(p_id));
    select *
      into l_action_item_rec
      from action_items
     where id = p_id;
    l_action_item_obj.put('_id',l_action_item_rec.id);
    l_action_item_obj.put('name',l_action_item_rec.name);
    l_action_item_obj.put('status',l_action_item_rec.status);
    select *
      bulk collect into l_team_members
      from action_item_team_members
     where action_id = p_id;
    for j in 1..l_team_members.count loop
        l_team_member_obj := json_object_t();
        l_team_member_obj.put('team_assignment_id',l_team_members(j).id);
        l_team_member_obj.put('role',l_team_members(j).role);
        l_team_member_obj.put('staff_id',l_team_members(j).user_id);
        -- Lookup staff name using id
        select name
          into l_team_member_name
          from staff
         where id = l_team_members(j).user_id;
        l_team_member_obj.put('name',l_team_member_name);
        -- Append team member object to the team array
        l_team_members_arr.append(l_team_member_obj);
    end loop;
    l_action_item_obj.put('team',l_team_members_arr);
    return l_action_item_obj;
end get_object_programmatically;

源示例 3:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- in package action_items_api
function get_object_using_sql(
    p_id in number)
return clob
is
    l_action_item_json_clob clob;
begin
    app_common.report_if_error(
        action_items_common.ensure_action_exists(p_id));
    select
json_object
(
      '_id' value ai.id,
      'name' value ai.name,
      'status' value ai.status,
      'team' value (
        select
json_arrayagg
(

json_object
(
            'team_assignment_id' value tm.id,
            'role' value tm.role,
            'staff_id' value tm.user_id,
            'name' value s.name
          )

returning clob
 /* json_arrayagg */)
        from action_item_team_members tm
        left join staff s on tm.user_id = s.id
        where tm.action_id = ai.id
      )

returning clob
 /* json_object */)
    into l_action_item_json_clob
    from action_items ai
    where ai.id = p_id;
    return l_action_item_json_clob;
end get_object_using_sql;

14.8.2.2 分页检索 Action Item#

本节对应官方主题“Retrieving Action Items with Paging”。中文学习稿把它放在“Action Items 集成示例”这条主线上理解:围绕 Action Items、Team Members 和负责人约束,理解外部系统为什么需要读写应用数据。

阅读时重点跟踪这些对象和概念:JSON。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.8.2.2 分页检索 Action Item”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.8.2.2 分页检索 Action Item”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:围绕 Action Items、Team Members 和负责人约束,理解外部系统为什么需要读写应用数据。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- in package action_items_api
function get_objects(
    p_search in varchar2,
    p_offset in number default null,
    p_limit  in number default null)
return json_object_t
is
    l_offset pls_integer := nvl(p_offset,0);
    l_limit  pls_integer := nvl(p_limit,25);
    l_ret json_object_t := json_object_t();
    l_items json_array_t := json_array_t();
    l_row_count  pls_integer := 0;
    l_total_rows pls_integer := 0;
begin
    for j in (select id, count(*) over() as total_count
                from action_items
               where upper(name) like upper('%'||p_search||'%')
               order by upper(name)
               offset l_offset rows
               fetch first l_limit rows only)
    loop
        if l_total_rows = 0 then
            l_total_rows := j.total_count;
        end if;
        l_row_count := l_row_count + 1;
        l_items.append(get_object(j.id));
    end loop;
    l_ret.put('items',l_items);
    l_ret.put('hasMore', l_offset + l_row_count < l_total_rows);
    l_ret.put('totalRows',l_total_rows);
    return l_ret;
end get_objects;

14.8.2.3 使用前置和后置逻辑修改 Action Item#

本节对应官方主题“Modifying Action Items with Pre/Post Logic”。中文学习稿把它放在“Action Items 集成示例”这条主线上理解:围绕 Action Items、Team Members 和负责人约束,理解外部系统为什么需要读写应用数据。

阅读时重点跟踪这些对象和概念:JSON、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.8.2.3 使用前置和后置逻辑修改 Action Item”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.8.2.3 使用前置和后置逻辑修改 Action Item”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:围绕 Action Items、Team Members 和负责人约束,理解外部系统为什么需要读写应用数据。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

14.8.2.4 检查核心 Action Item API 包体#

本节对应官方主题“Inspecting the Core Action Item API Body”。中文学习稿把它放在“Action Items 集成示例”这条主线上理解:围绕 Action Items、Team Members 和负责人约束,理解外部系统为什么需要读写应用数据。

阅读时重点跟踪这些对象和概念:JSON。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.8.2.4 检查核心 Action Item API 包体”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.8.2.4 检查核心 Action Item API 包体”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:围绕 Action Items、Team Members 和负责人约束,理解外部系统为什么需要读写应用数据。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

create or replace package body action_items_api as

    subtype t_get_object_approach is pls_integer range 1..2;
    c_approach_programmatic constant t_get_object_approach := 1;
    c_approach_sql          constant t_get_object_approach := 2;

    subtype t_operation is pls_integer range 1..3;
    c_operation_insert      constant t_operation := 1;
    c_operation_update      constant t_operation := 2;
    c_operation_delete      constant t_operation := 3;

    ------------------------------------
    procedure before_save(
        p_action_item  in out action_items%rowtype,
        p_action_item_team_members in out t_action_item_team_members,
        p_operation    in     t_operation)
    is
    begin
        if p_operation = c_operation_insert then
            -- Providing an ID with insert not allowed
            app_common.report_if_error(
                action_items_common.ensure_null_id_for_new_action(p_action_item.id));
        end if;
        if p_operation in (c_operation_insert,c_operation_update) then
            -- Default role to member if not supplied
            for j in 1..p_action_item_team_members.count loop
                if p_action_item_team_members(j).role is null then
                    p_action_item_team_members(j).role := 'MEMBER';
                else
                    -- Check role value is legal
                    app_common.report_if_error(
                        action_items_common.is_valid_role(p_action_item_team_members(j).role));
                end if;
            end loop;
        end if;
    end before_save;
    ------------------------------------
    procedure save(
        p_action_item              in out action_items%rowtype,
        p_action_item_team_members in out t_action_item_team_members,
        p_operation                in     t_operation)
    is
        l_new_ids                apex_t_number;
        l_action_item_member_ids apex_t_number := apex_t_number();
    begin
        case p_operation
            when c_operation_insert then
                -- insert the action item
                insert into action_items(name)
                values (p_action_item.name)
                returning id into p_action_item.id;
                -- Set foreign key attribute for new child rows
                for i in 1..p_action_item_team_members.count loop
                    p_action_item_team_members(i).action_id := p_action_item.id;
                end loop;
                -- insert all the team members
                forall i in 1..p_action_item_team_members.count
                    insert into action_item_team_members values p_action_item_team_members(i)
                    returning id bulk collect into l_new_ids;
                -- Populate the system-assigned id
                for i in 1..p_action_item_team_members.count loop
                    p_action_item_team_members(i).id := l_new_ids(i);
                end loop;
            when c_operation_update then
                update action_items
                set name = p_action_item.name,
                    status = p_action_item.status
                where id = p_action_item.id;
                -- Insert/update child rows that need inserting, populating assigned id
                for i in 1..p_action_item_team_members.count loop
                    if p_action_item_team_members(i).id is null then
                        -- id is null? Needs an insert
                        insert into action_item_team_members
                        values p_action_item_team_members(i)
                        returning id into p_action_item_team_members(i).id;
                    else
                        -- id is not null, needs an update
                        update action_item_team_members
                        set role = p_action_item_team_members(i).role,
                            user_id = p_action_item_team_members(i).user_id
                        where id = p_action_item_team_members(i).id
                          and action_id = p_action_item_team_members(i).action_id;
                    end if;
                    -- track which ids we updated and inserted so we can delete others
                    l_action_item_member_ids.extend;
                    l_action_item_member_ids(l_action_item_member_ids.count)
                        := p_action_item_team_members(i).id;
                end loop;
                -- Delete any existing team members who are not among the updates
                delete from action_item_team_members
                where action_id = p_action_item.id
                and id not in (select column_value from table(l_action_item_member_ids));
            when c_operation_delete then
                delete from action_items
                 where id = p_action_item.id;
        end case;
    end save;
    ------------------------------------
    procedure after_save(
        p_action_item              in action_items%rowtype,
        p_action_item_team_members in t_action_item_team_members,
        p_operation                in t_operation)
    is
    begin
        if p_operation in (c_operation_insert,c_operation_update) then
            app_common.report_if_error(
                action_items_common.no_duplicate_team_members(p_action_item.id));
            app_common.report_if_error(
                action_items_common.one_lead_per_action_team(p_action_item.id));
        end if;
    end after_save;
    ------------------------------------
    procedure action_item_json_to_record(
        p_object        in json_object_t,
        p_action_item  out action_items%rowtype,
        p_action_item_team_members out t_action_item_team_members)
    is
        l_team_members_arr json_array_t;
        l_team_member_obj  json_object_t;
        l_team_member_rec  action_item_team_members%rowtype;
        l_team_member_name staff.name%type;
    begin
        p_action_item.id     := p_object.get_number('_id');
        p_action_item.name   := p_object.get_string('name');
        p_action_item.status := p_object.get_string('status');
        p_action_item_team_members := t_action_item_team_members();
        l_team_members_arr := p_object.get_array('team');
        for j in 0..l_team_members_arr.get_size - 1 loop
            -- Fill in foreign key attribute from parent
            l_team_member_rec := null;
            l_team_member_rec.action_id := p_action_item.id;
            l_team_member_obj := treat(l_team_members_arr.get(j) as json_object_t);
            l_team_member_rec.id      := l_team_member_obj.get_number('team_assignment_id');
            l_team_member_rec.user_id := l_team_member_obj.get_string('staff_id');
            -- if user_id is null, try to use name to look it up since name is unique
            if l_team_member_rec.user_id is null then
                l_team_member_name := l_team_member_obj.get_string('name');
                if l_team_member_name is not null then
                    begin
                        select id
                          into l_team_member_rec.user_id
                          from staff
                         where name = l_team_member_name;
                    exception
                        when no_data_found then
                            app_common.report_error_key(
                                'TEAM_MEMBER_NOT_FOUND',
                                apex_t_varchar2('name',l_team_member_name));
                    end;
                end if;
            end if;
            l_team_member_rec.role := substr(l_team_member_obj.get_string('role'),1,6);
            p_action_item_team_members.extend;
            p_action_item_team_members(p_action_item_team_members.count) := l_team_member_rec;
        end loop;
    end action_item_json_to_record;
    ------------------------------------
    function get_object_using_sql(
        p_id in number)
    return clob
    is
        l_action_item_json_clob clob;
    begin
        app_common.report_if_error(
            action_items_common.ensure_action_exists(p_id));
        select json_object(
          '_id' value ai.id,
          'name' value ai.name,
          'status' value ai.status,
          'team' value (
            select json_arrayagg(
              json_object(
                'team_assignment_id' value tm.id,
                'role' value tm.role,
                'staff_id' value tm.user_id,
                'name' value s.name
              )
            returning clob /* json_arrayagg */)
            from action_item_team_members tm
            left join staff s on tm.user_id = s.id
            where tm.action_id = ai.id
          )
        returning clob /* json_object */)
        into l_action_item_json_clob
        from action_items ai
        where ai.id = p_id;
        return l_action_item_json_clob;
    end get_object_using_sql;
    ------------------------------------
    function get_object_programmatically(
        p_id in number)
    return json_object_t
    is
        l_action_item_rec action_items%rowtype;
        l_action_item_obj json_object_t := json_object_t();
        l_team_members_arr json_array_t := json_array_t();
        l_team_members     t_action_item_team_members := t_action_item_team_members();
        l_team_member_obj  json_object_t;
        l_team_member_name staff.name%type;
    begin
        app_common.report_if_error(
            action_items_common.ensure_action_exists(p_id));
        select *
          into l_action_item_rec
          from action_items
         where id = p_id;
        l_action_item_obj.put('_id',l_action_item_rec.id);
        l_action_item_obj.put('name',l_action_item_rec.name);
        l_action_item_obj.put('status',l_action_item_rec.status);
        select *
          bulk collect into l_team_members
          from action_item_team_members
         where action_id = p_id;
        for j in 1..l_team_members.count loop
            l_team_member_obj := json_object_t();
            l_team_member_obj.put('team_assignment_id',l_team_members(j).id);
            l_team_member_obj.put('role',l_team_members(j).role);
            l_team_member_obj.put('staff_id',l_team_members(j).user_id);
            -- Lookup staff name using id
            select name
              into l_team_member_name
              from staff
             where id = l_team_members(j).user_id;
            l_team_member_obj.put('name',l_team_member_name);
            -- Append team member object to the team array
            l_team_members_arr.append(l_team_member_obj);
        end loop;
        l_action_item_obj.put('team',l_team_members_arr);
        return l_action_item_obj;
    end get_object_programmatically;
    ------------------------------------
    function get_object(
        p_id in number)
    return json_object_t
    is
        c_get_object_approach   constant t_get_object_approach := c_approach_sql;
        l_ret json_object_t;
    begin
        case c_get_object_approach
            when c_approach_programmatic then
                l_ret := get_object_programmatically(p_id);
            when c_approach_sql then
                l_ret := json_object_t(get_object_using_sql(p_id));
        end case;
        return l_ret;
    end;
    ------------------------------------
    function get_objects(
        p_search in varchar2,
        p_offset in number default null,
        p_limit  in number default null)
    return json_object_t
    is
        l_offset pls_integer := nvl(p_offset,0);
        l_limit  pls_integer := nvl(p_limit,25);
        l_ret json_object_t := json_object_t();
        l_items json_array_t := json_array_t();
        l_row_count  pls_integer := 0;
        l_total_rows pls_integer := 0;
    begin
        for j in (select id, count(*) over() as total_count
                    from action_items
                   where upper(name) like upper('%'||p_search||'%')
                   order by upper(name)
                   offset l_offset rows
                   fetch first l_limit rows only)
        loop
            if l_total_rows = 0 then
                l_total_rows := j.total_count;
            end if;
            l_row_count := l_row_count + 1;
            l_items.append(get_object(j.id));
        end loop;
        l_ret.put('items',l_items);
        l_ret.put('hasMore', l_offset + l_row_count < l_total_rows);
        l_ret.put('totalRows',l_total_rows);
        return l_ret;
    end get_objects;
    ------------------------------------
    function insert_object(
        p_object in json_object_t)
    return json_object_t
    is
        l_action_item_rec action_items%rowtype;
        l_action_item_team_members t_action_item_team_members;
    begin
        action_item_json_to_record(
            p_object                   => p_object,
            p_action_item              => l_action_item_rec,
            p_action_item_team_members => l_action_item_team_members);
        before_save(l_action_item_rec,l_action_item_team_members,c_operation_insert);
        save(l_action_item_rec,l_action_item_team_members,c_operation_insert);
        after_save(l_action_item_rec,l_action_item_team_members,c_operation_insert);
        return get_object(l_action_item_rec.id);
    end insert_object;
    ------------------------------------
    function update_object(
        p_object in json_object_t)
    return json_object_t
    is
        l_action_item_rec action_items%rowtype;
        l_action_item_team_members t_action_item_team_members;
    begin
        action_item_json_to_record(
            p_object                   => p_object,
            p_action_item              => l_action_item_rec,
            p_action_item_team_members => l_action_item_team_members);
        before_save(l_action_item_rec,l_action_item_team_members,c_operation_update);
        save(l_action_item_rec,l_action_item_team_members,c_operation_update);
        after_save(l_action_item_rec,l_action_item_team_members,c_operation_update);
        return get_object(l_action_item_rec.id);
    end update_object;
    ------------------------------------
    procedure delete_object(
        p_id in number)
    is
        l_action_item_rec action_items%rowtype;
        l_action_item_team_members t_action_item_team_members;
    begin
        l_action_item_rec.id := p_id;
        before_save(l_action_item_rec,l_action_item_team_members,c_operation_delete);
        save(l_action_item_rec,l_action_item_team_members,c_operation_delete);
        after_save(l_action_item_rec,l_action_item_team_members,c_operation_delete);
    end delete_object;
end action_items_api;

14.9.1.1 存储并访问 JSON 类型数据#

本节对应官方主题“Storing and Accessing JSON Type Data”。中文学习稿把它放在“Oracle 26ai 的 JSON 简化路径”这条主线上理解:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。

阅读时重点跟踪这些对象和概念:JSON、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.1.1 存储并访问 JSON 类型数据”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.9.1.1 存储并访问 JSON 类型数据”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

l_actionitem json :=
             json(q'~
                {
                  "name": "Practice Using JSON in PL/SQL",
                  "team": [
                    {"name": "Georgia","role": "LEAD"},
                    {"name": "Quinn"},
                    {"name": "Zelda"}
                  ]
                }
              ~');

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- Default role to member if not supplied
select
   json_transform(l_actionitem,
      set '$.team[*]?(@.role == null || !exists(@.role)).role'
           = 'MEMBER')
    into l_actionitem;

源示例 3:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- Print out the name of the LEAD team member
p(json_value(l_actionitem,'$.team[*]?(@.role == "LEAD").name'));

源示例 4:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- Process each team member object in a loop
for k in (select team_member
            from json_table(l_actionitem,'$.team[*]'
                    columns (team_member json path '$')))
loop
    p(json_value(k.team_member,'$.name')||','||
      json_value(k.team_member,'$.role'));
end loop;  

源示例 5:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- Delete team member Zelda using SQL
select json_transform(l_actionitem,
            remove '$.team[*]?(@.name == "Zelda" && @.role == "MEMBER")')
  into l_actionitem;

源示例 6:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- Delete team member Quinn using PL/SQL JSON_OBJECT_T
l_actionitem_obj := json_object_t(l_actionitem);
l_teammembers    := l_actionitem_obj.get_array('team');
-- iterate backwards for deleting
for j in reverse 0..l_teammembers.get_size - 1  loop
    if get_object(l_teammembers,j).get_string('name') = 'Quinn' then
        l_teammembers.remove(j);
    end if;
end loop;
-- Show interoperability between JSON and JSON_OBJECT_T
l_actionitem := l_actionitem_obj.to_json;

源示例 7:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

declare
    l_actionitem json :=
                 json(q'~
                    {
                      "name": "Practice Using JSON in PL/SQL",
                      "team": [
                        {"name": "Georgia","role": "LEAD"},
                        {"name": "Quinn"},
                        {"name": "Zelda"}
                      ]
                    }
                  ~');
    l_actionitem_obj json_object_t;
    l_teammembers    json_array_t;
    -----------------------------
    function get_object(
        p_array in json_array_t,
        p_index in pls_integer)
        return     json_object_t
    is
    begin
        return treat(p_array.get(p_index) as json_object_t);
    end get_object;
    -----------------------------
    procedure p(p_str in varchar)
    is
    begin
        dbms_output.put_line(p_str);
    end p;
begin
    -- Default role to member if not supplied
    select json_transform(l_actionitem,
                set '$.team[*]?(@.role == null
                                ||!exists(@.role))
                                .role' = 'MEMBER')
    into l_actionitem;
    p(json_serialize(l_actionitem pretty));
    -- Print out the name of the LEAD team member
    p(json_value(l_actionitem,'$.team[*]?(@.role == "LEAD").name'));
    -- Process each team member object in a loop
    for k in (select team_member
                from json_table(l_actionitem,'$.team[*]'
                        columns (team_member json path '$')))
    loop
        p(json_value(k.team_member,'$.name')||','||
          json_value(k.team_member,'$.role'));
    end loop;
    -- Delete team member Zelda using SQL
    select json_transform(l_actionitem,
                remove '$.team[*]?(@.name == "Zelda" && @.role == "MEMBER")')
      into l_actionitem;
    p(json_serialize(l_actionitem pretty));
    -- Delete team member Quinn using PL/SQL JSON_OBJECT_T
    l_actionitem_obj := json_object_t(l_actionitem);
    l_teammembers    := l_actionitem_obj.get_array('team');
    -- iterate backwards for deleting
    for j in reverse 0..l_teammembers.get_size - 1  loop
        if get_object(l_teammembers,j).get_string('name') = 'Quinn' then
            l_teammembers.remove(j);
        end if;
    end loop;
    -- Show interoperability between JSON and JSON_OBJECT_T
    l_actionitem := l_actionitem_obj.to_json;
    p(json_serialize(l_actionitem pretty));
end;

源示例 8:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

{
  "name" : "Practice Using JSON in PL/SQL",
  "team" :
  [
    {
      "name" : "Georgia",
      "role" : "LEAD"
    },
    {
      "name" : "Quinn",
      "role" : "MEMBER"
    },
    {
      "name" : "Zelda",
      "role" : "MEMBER"
    }
  ]
}
Georgia
Georgia,LEAD
Quinn,MEMBER
Zelda,MEMBER
{
  "name" : "Practice Using JSON in PL/SQL",
  "team" :
  [
    {
      "name" : "Georgia",
      "role" : "LEAD"
    },
    {
      "name" : "Quinn",
      "role" : "MEMBER"
    }
  ]
}
{
  "name" : "Practice Using JSON in PL/SQL",
  "team" :
  [
    {
      "name" : "Georgia",
      "role" : "LEAD"
    }
  ]
}

14.9.1.2 定义 JSON Relational Duality View#

本节对应官方主题“Defining JSON Relational Duality View”。中文学习稿把它放在“Oracle 26ai 的 JSON 简化路径”这条主线上理解:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。

阅读时重点跟踪这些对象和概念:JSON、JSON Relational Duality View。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.1.2 定义 JSON Relational Duality View”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.9.1.2 定义 JSON Relational Duality View”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

create json relational duality view
action_items_dv
 as

action_items

@insert @update @delete

{
  _id: id,
  name: name,
  status: status,
  team:
action_item_team_members

@insert @update @delete

  {
    team_assignment_id: id,
    role: role,

staff

@unnest

    {
      staff_id: id,
      name: name
    }
  }
};

14.9.1.3 查询 JSON Relational Duality View#

本节对应官方主题“Querying JSON Relational Duality View”。中文学习稿把它放在“Oracle 26ai 的 JSON 简化路径”这条主线上理解:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。

阅读时重点跟踪这些对象和概念:JSON、ETAG、JSON Relational Duality View。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.1.3 查询 JSON Relational Duality View”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.9.1.3 查询 JSON Relational Duality View”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- Retrieve 3 action item JSON docs by _id value
select data
  from action_items_dv
 where json_value(data,'$._id') in (14, 25, 27)

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

{
  "_id": 14,
  "name": "End of Year Party",
  "status": "OPEN",
  "team": [
    {
      "team_assignment_id": 23,
      "role": "MEMBER",
      "staff_id": 4,
      "name": "David"
    },
    {
      "team_assignment_id": 24,
      "role": "LEAD",
      "staff_id": 5,
      "name": "Georgia"
    },
    {
      "team_assignment_id": 25,
      "role": "MEMBER",
      "staff_id": 13,
      "name": "Jane"
    }
  ],
  "_metadata": {
    "etag": "5891809CF5691D5400D4141A65123976",
    "asof": "000025C52A64CB47"
  }
}

14.9.1.4 通过双重性视图修改 JSON#

本节对应官方主题“Modifying JSON Using a Duality View”。中文学习稿把它放在“Oracle 26ai 的 JSON 简化路径”这条主线上理解:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。

阅读时重点跟踪这些对象和概念:JSON、ETAG、JSON Relational Duality View。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.1.4 通过双重性视图修改 JSON”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.9.1.4 通过双重性视图修改 JSON”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

declare
    l_json json :=
           json(q'~
            {
              "name": "Buy Talulah's Retirement Gift",
              "team": [
                {
                  "role": "LEAD",
                  "name": "Abigail"
                },
                {
                  "role": "MEMBER",
                  "name": "Chaz"
                }
              ]
            }
       ~');
begin

insert into action_items_dv(data)
    values (l_json)
    returning data into l_json
;
    dbms_output.put_line(json_serialize(l_json pretty));
end;

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

{
  "_id" : 58,
  "name" : "Buy Talulah's Retirement Gift",
  "status": "OPEN",
  "team" :
  [
    {
      "team_assignment_id" : 127,
      "role" : "MEMBER",
      "staff_id" : 23,
      "name" : "Chaz"
    },
    {
      "team_assignment_id" : 128,
      "role" : "LEAD",
      "staff_id" : 18,
      "name" : "Abigail"
    }
  ],
  "_metadata" :
  {
    "etag" : "48A8D3D393B6653A5D2B0359EDAD2D21",
    "asof" : "000025C52A6F11EE"
  }
}

14.9.1.5 体验双重性视图的双向能力#

本节对应官方主题“Flexing the Duality of Duality Views”。中文学习稿把它放在“Oracle 26ai 的 JSON 简化路径”这条主线上理解:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。

阅读时重点跟踪这些对象和概念:JSON。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.1.5 体验双重性视图的双向能力”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.9.1.5 体验双重性视图的双向能力”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-31 体验双重性视图的双向能力:官方捕获图片 1

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

select ai.name as action_name, s.name, tm.role
  from action_item_team_members tm
  join action_items ai
    on ai.id = tm.action_id
  join staff s
    on s.id = tm.user_id
 where ai.id = 58
 order by tm.role, s.name

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

ACTION_NAME                    NAME      ROLE
-----------------------------  --------  ------
Buy Talulah's Retirement Gift  Abigail   LEAD
Buy Talulah's Retirement Gift  Chaz      MEMBER

14.9.1.6 使用 ETAG 防止丢失更新#

本节对应官方主题“Preventing Lost Updates with ETAG”。中文学习稿把它放在“集成 API 学习路径”这条主线上理解:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。

阅读时重点跟踪这些对象和概念:JSON、PL/SQL、SQL、ETAG、JSON Relational Duality View。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.1.6 使用 ETAG 防止丢失更新”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.9.1.6 使用 ETAG 防止丢失更新”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

declare
    l_json json :=
           -- Modified original JSON document
           -- to swap Chaz with Usha
           json(q'~
            {
              "_id" : 58,
              "name" : "Buy Talulah's Retirement Gift",
              "team" :
              [
                {
                  "role" : "MEMBER",
                  "name" : "Usha"
                },
                {
                  "team_assignment_id" : 128,
                  "role" : "LEAD",
                  "staff_id" : 18,
                  "name" : "Abigail"
                }
              ],
              "_metadata" :
              {
                "etag" : "48A8D3D393B6653A5D2B0359EDAD2D21",
                "asof" : "000025C52A6F11EE"
              }
            }
       ~');
begin
    update action_items_dv
       set data =  l_json
     where json_value(data,'$._id') = 58
    returning data into l_json;
    dbms_output.put_line(json_serialize(l_json pretty));
end;

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

ORA-42699: Cannot update JSON Relational Duality View 'ACTION_ITEMS_DV':
  The ETAG of document with ID 'FB03C13B00' in the database did not match
  the ETAG passed in.

源示例 3:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

"_metadata" : {
   "
etag
" : "
48A8D3D393B6653A5D2B0359EDAD2D21
",
   "asof" : "000025C52A6F11EE"
}

14.9.1.7 比较双重性视图中的 _id 和 RESID#

本节对应官方主题“Comparing _id and RESID in Duality View”。中文学习稿把它放在“Oracle 26ai 的 JSON 简化路径”这条主线上理解:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。

阅读时重点跟踪这些对象和概念:REST、JSON、PL/SQL、SQL、ETAG、JSON Relational Duality View。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.1.7 比较双重性视图中的 _id 和 RESID”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.9.1.7 比较双重性视图中的 _id 和 RESID”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

ORA-42699: Cannot update JSON Relational Duality View 'ACTION_ITEMS_DV':
  The ETAG of document with ID 'FB03C13B00' in the database did not match
  the ETAG passed in.

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

WHERE RESID =
l_resid_var_raw

源示例 3:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

WHERE JSON_VALUE(data,'$._id') =
l_id_value

14.9.2.1 为双重性视图启用 AutoREST#

本节对应官方主题“Enabling AutoREST for a Duality View”。中文学习稿把它放在“Oracle 26ai 的 JSON 简化路径”这条主线上理解:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。

阅读时重点跟踪这些对象和概念:REST、ORDS、SQL、AutoREST、SQL Developer Web。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.2.1 为双重性视图启用 AutoREST”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.9.2.1 为双重性视图启用 AutoREST”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。
图 14-32 为双重性视图启用 AutoREST:官方捕获图片 1
图 14-33 为双重性视图启用 AutoREST:官方捕获图片 2
图 14-34 为双重性视图启用 AutoREST:官方捕获图片 3

14.9.2.2 练习调用双重性视图 AutoREST 端点#

本节对应官方主题“Exercising Duality View AutoREST Endpoint”。中文学习稿把它放在“Oracle 26ai 的 JSON 简化路径”这条主线上理解:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。

阅读时重点跟踪这些对象和概念:REST、ORDS、JSON、AutoREST、JSON Relational Duality View。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.2.2 练习调用双重性视图 AutoREST 端点”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.9.2.2 练习调用双重性视图 AutoREST 端点”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

{
    "name": "New Product Promotion Deck",
    "team": [
        {
            "role": "LEAD",
            "name": "Usha"
        },
        {"name": "Leopoldo"}
    ]
}

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

ORA-40937: Cannot insert into table 'STAFF' in JSON Relational Duality View
           'ACTION_ITEMS_DV': Missing INSERT annotation

14.9.2.3 执行更复杂的业务逻辑#

本节对应官方主题“Enforcing More Complex Business Logic”。中文学习稿把它放在“业务规则复用”这条主线上理解:把页面和 REST API 共享的默认值、校验、错误消息和回滚语义集中在数据库包中,避免两套入口产生不一致。

阅读时重点跟踪这些对象和概念:REST、ORDS、PL/SQL、SQL、AutoREST。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.2.3 执行更复杂的业务逻辑”,说明它解决的核心问题是页面和 REST API 共享业务规则、错误消息和事务回滚。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一条非法数据无论来自页面还是 API,都会得到一致的校验失败。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Developer Web 的 REST Designer 与 ORDS Service Definitions。
  • 操作:根据本节主题“14.9.2.3 执行更复杂的业务逻辑”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把页面和 REST API 共享的默认值、校验、错误消息和回滚语义集中在数据库包中,避免两套入口产生不一致。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

{
    "name": "New Product Pitch Deck",
    "team": [
        {"name": "David"},
        {"name": "Georgia"},
        {"name": "Jane"},
        {"name": "Georgia"}
    ]
}

14.9.4.1 无需解析即可用 SQL 保存 JSON#

本节对应官方主题“Saving JSON Using SQL Without Parsing”。中文学习稿把它放在“JSON 数据处理”这条主线上理解:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。

阅读时重点跟踪这些对象和概念:JSON、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.4.1 无需解析即可用 SQL 保存 JSON”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.9.4.1 无需解析即可用 SQL 保存 JSON”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- in package actions_items_dv_api
procedure save(
    p_action_item in out json,
    p_operation   in     t_operation)
is
begin
    case p_operation
        when c_operation_insert then

insert into action_items_dv
(data)
            values (p_action_item)
            returning data into p_action_item;
        when c_operation_update then

update action_items_dv

               set data = p_action_item
             where json_value(data,'$."_id"')
                   = json_value(p_action_item,'$."_id"');
        when c_operation_delete then

delete from action_items_dv

             where json_value(data,'$."_id"')
                   = json_value(p_action_item,'$."_id"');
    end case;
end save;

14.9.4.2 在 SQL 中声明式转换 JSON#

本节对应官方主题“Transforming JSON Declaratively in SQL”。中文学习稿把它放在“JSON 数据处理”这条主线上理解:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。

阅读时重点跟踪这些对象和概念:JSON、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.4.2 在 SQL 中声明式转换 JSON”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.9.4.2 在 SQL 中声明式转换 JSON”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- Default role to member if not supplied
select json_transform(p_action_item,
            set '$.team[*]?(@.role == null ||
                             !exists(@.role)).role' = 'MEMBER')
into p_action_item;

14.9.4.3 更轻松地处理和访问 JSON#

本节对应官方主题“Processing and Accessing JSON Easily”。中文学习稿把它放在“JSON 数据处理”这条主线上理解:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。

阅读时重点跟踪这些对象和概念:JSON。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.4.3 更轻松地处理和访问 JSON”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.9.4.3 更轻松地处理和访问 JSON”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- Ensure role values are legal
for k in (select team_member
            from json_table(p_action_item,'$.team[*]'
                 columns (team_member json path '$')))
loop
    app_common.report_if_error(
        action_items_common.is_valid_role(
            json_value(k.team_member,'$.role')));
end loop;

14.9.4.4 查询预定义 JSON 结构#

本节对应官方主题“Querying Predefined JSON Structure”。中文学习稿把它放在“JSON 数据处理”这条主线上理解:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。

阅读时重点跟踪这些对象和概念:JSON。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.4.4 查询预定义 JSON 结构”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.9.4.4 查询预定义 JSON 结构”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:理解 JSON 文档如何在 SQL、PL/SQL、HTTP 请求和响应之间流动,并保持属性名、数组和对象结构稳定。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

function get_object(
    p_id in number)
return json
is
    l_ret json;
begin
    app_common.report_if_error(
        action_items_common.ensure_action_exists(p_id));
    select
data

      into l_ret
      from
action_items_dv

      where json_value(data,'$."_id"') = p_id;
    return l_ret;
end get_object;

14.9.4.5 检查核心 26ai Action Item API#

本节对应官方主题“Inspecting the Core 26ai Action Item API”。中文学习稿把它放在“Oracle 26ai 的 JSON 简化路径”这条主线上理解:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。

阅读时重点跟踪这些对象和概念:JSON。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.9.4.5 检查核心 26ai Action Item API”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.9.4.5 检查核心 26ai Action Item API”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:观察 JSON 类型、JSON Relational Duality View 和 AutoREST 如何减少手写解析、拼接和同步逻辑。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

package body action_items_dv_api as

    subtype t_operation is pls_integer range 1..3;
    c_operation_insert      constant t_operation := 1;
    c_operation_update      constant t_operation := 2;
    c_operation_delete      constant t_operation := 3;

    ------------------------------------
    procedure before_save(
        p_action_item in out json,
        p_operation   in     t_operation)
    is
    begin
        if p_operation = c_operation_insert then
            -- Providing an ID with insert not allowed
            app_common.report_if_error(
                action_items_common.ensure_null_id_for_new_action(
                    json_value(p_action_item,'$."_id"')));
        end if;
        if p_operation in (c_operation_insert,c_operation_update) then
            -- Ensure role values are legal
            for k in (select team_member
                        from json_table(p_action_item,'$.team[*]'
                             columns (team_member json path '$')))
            loop
                app_common.report_if_error(
                    action_items_common.is_valid_role(
                        json_value(k.team_member,'$.role')));
            end loop;
            -- Default role to member if not supplied
            select json_transform(p_action_item,
                        set '$.team[*]?(@.role == null ||
                                         !exists(@.role)).role' = 'MEMBER')
            into p_action_item;
        end if;
    end before_save;
    ------------------------------------
    procedure save(
        p_action_item in out json,
        p_operation   in     t_operation)
    is
    begin
        case p_operation
            when c_operation_insert then
                insert into action_items_dv(data)
                values (p_action_item)
                returning data into p_action_item;
            when c_operation_update then
                update action_items_dv
                   set data = p_action_item
                 where json_value(data,'$."_id"')
                       = json_value(p_action_item,'$."_id"');
            when c_operation_delete then
                delete from action_items_dv
                 where json_value(data,'$."_id"')
                       = json_value(p_action_item,'$."_id"');
        end case;
    end save;
    ------------------------------------
    procedure after_save(
        p_action_item in json,
        p_operation   in t_operation)
    is
        l_error varchar2(4000);
        l_id number := json_value(p_action_item,'$."_id"');
    begin
        if p_operation in (c_operation_insert,c_operation_update) then
            app_common.report_if_error(
                action_items_common.no_duplicate_team_members(l_id));
            app_common.report_if_error(
                action_items_common.one_lead_per_action_team(l_id));
        end if;
    end after_save;
    ------------------------------------
    function get_object(
        p_id in number)
    return json
    is
        l_ret json;
    begin
        app_common.report_if_error(
            action_items_common.ensure_action_exists(p_id));
        select data
          into l_ret
          from action_items_dv
          where json_value(data,'$."_id"') = p_id;
        return l_ret;
    end get_object;
    ------------------------------------
    function get_objects(
        p_search in varchar2,
        p_offset in number default null,
        p_limit  in number default null)
    return json
    is
        l_offset pls_integer := nvl(p_offset,0);
        l_limit  pls_integer := nvl(p_limit,25);
        l_ret json_object_t := json_object_t();
        l_items json_array_t := json_array_t();
        l_row_count  pls_integer := 0;
        l_total_rows pls_integer := 0;
    begin
        for j in (select json_value(data,'$."_id"') id,
                         count(*) over() as total_count
                    from action_items_dv
                   where upper(json_value(data,'$.name'))
                         like upper('%'||p_search||'%')
                   order by upper(json_value(data,'$.name'))
                   offset l_offset rows
                   fetch first l_limit rows only)
        loop
            if l_total_rows = 0 then
                l_total_rows := j.total_count;
            end if;
            l_row_count := l_row_count + 1;
            l_items.append(json_object_t(get_object(j.id)));
        end loop;
        l_ret.put('items',l_items);
        l_ret.put('hasMore', l_offset + l_row_count < l_total_rows);
        l_ret.put('totalRows',l_total_rows);
        return l_ret.to_json;
    end get_objects;
    ------------------------------------
    function insert_object(
        p_object in json)
    return json
    is
        l_object json := p_object;
    begin
        before_save(l_object,c_operation_insert);
        save(l_object,c_operation_insert);
        after_save(l_object,c_operation_insert);
        return get_object(json_value(l_object,'$."_id"'));
    end insert_object;
    ------------------------------------
    function update_object(
        p_object in json)
    return json
    is
        l_object json := p_object;
    begin
        before_save(l_object,c_operation_update);
        save(l_object,c_operation_update);
        after_save(l_object,c_operation_update);
        return get_object(json_value(l_object,'$."_id"'));
    end update_object;
    ------------------------------------
    procedure delete_object(
        p_id in number)
    is
        l_id_only_object json_object_t := json_object_t();
        l_object json;
    begin
        l_id_only_object.put('_id',p_id);
        l_object := l_id_only_object.to_json;
        save(l_object,c_operation_delete);
    end delete_object;
end action_items_dv_api;
14.8.2.3.1 从 JSON 填充 PL/SQL 记录#

本节对应官方主题“Populating PL/SQL Records from JSON”。中文学习稿把它放在“ORDS 服务建模”这条主线上理解:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。

阅读时重点跟踪这些对象和概念:JSON、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.8.2.3.1 从 JSON 填充 PL/SQL 记录”,说明它解决的核心问题是JSON 文档、关系数据和 Oracle 26ai 简化能力之间的映射关系。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一业务数据可以稳定地以 JSON 或关系行形式读取、修改和验证。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.8.2.3.1 从 JSON 填充 PL/SQL 记录”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把模块、URL template、HTTP method、handler、参数和返回内容作为一个可测试的服务契约来处理。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- in package action_items_api
procedure
action_item_json_to_record
(
    p_object        in json_object_t,
    p_action_item  out action_items%rowtype,
    p_action_item_team_members out t_action_item_team_members)
is
    l_team_members_arr json_array_t;
    l_team_member_obj  json_object_t;
    l_team_member_rec  action_item_team_members%rowtype;
    l_team_member_name staff.name%type;
begin
    p_action_item.id     := p_object.get_number('_id');
    p_action_item.name   := p_object.get_string('name');
    p_action_item.status := p_object.get_string('status');
    p_action_item_team_members := t_action_item_team_members();
    l_team_members_arr := p_object.get_array('team');
    for j in 0..l_team_members_arr.get_size - 1 loop
        -- Fill in foreign key attribute from parent
        l_team_member_rec := null;
        l_team_member_rec.action_id := p_action_item.id;
        l_team_member_obj := treat(l_team_members_arr.get(j) as json_object_t);
        l_team_member_rec.id      := l_team_member_obj.get_number('team_assignment_id');
        l_team_member_rec.user_id := l_team_member_obj.get_string('staff_id');
        -- if user_id is null, try to use name to look it up since name is unique
        if l_team_member_rec.user_id is null then
            l_team_member_name := l_team_member_obj.get_string('name');
            if l_team_member_name is not null then
                begin
                    select id
                      into l_team_member_rec.user_id
                      from staff
                     where name = l_team_member_name;
                exception
                    when no_data_found then
                        app_common.report_error_key(
                            'TEAM_MEMBER_NOT_FOUND',
                            apex_t_varchar2('name',l_team_member_name));
                end;
            end if;
        end if;
        l_team_member_rec.role := substr(l_team_member_obj.get_string('role'),1,6);
        p_action_item_team_members.extend;
        p_action_item_team_members(p_action_item_team_members.count)
            := l_team_member_rec;
    end loop;
end action_item_json_to_record;
14.8.2.3.2 将 Action Item 数据保存到表#

本节对应官方主题“Saving Action Item Data to Tables”。中文学习稿把它放在“Action Items 集成示例”这条主线上理解:围绕 Action Items、Team Members 和负责人约束,理解外部系统为什么需要读写应用数据。

阅读时重点跟踪这些对象和概念:REST API、ORDS、JSON 与共享业务逻辑。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.8.2.3.2 将 Action Item 数据保存到表”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop / RESTful Services / SQL Developer Web REST Designer。
  • 操作:根据本节主题“14.8.2.3.2 将 Action Item 数据保存到表”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:围绕 Action Items、Team Members 和负责人约束,理解外部系统为什么需要读写应用数据。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- in package action_items_api
procedure save(
    p_action_item              in out action_items%rowtype,
    p_action_item_team_members in out t_action_item_team_members,
    p_operation                in     t_operation)
is
    l_new_ids                apex_t_number;
    l_action_item_member_ids apex_t_number := apex_t_number();
begin
    case p_operation
        when c_operation_insert then
            -- insert the action item
            insert into action_items(name)
            values (p_action_item.name)
            returning id into p_action_item.id;
            -- Set foreign key attribute for new child rows
            for i in 1..p_action_item_team_members.count loop
                p_action_item_team_members(i).action_id := p_action_item.id;
            end loop;
            -- insert all the team members
            forall i in 1..p_action_item_team_members.count
                insert into action_item_team_members
                values p_action_item_team_members(i)
                returning id bulk collect into l_new_ids;
            -- Populate the system-assigned id
            for i in 1..p_action_item_team_members.count loop
                p_action_item_team_members(i).id := l_new_ids(i);
            end loop;
        when c_operation_update then
            update action_items
            set name = p_action_item.name,
                status = p_action_item.status
            where id = p_action_item.id;
            -- Insert/update child rows that need inserting, populating assigned id
            for i in 1..p_action_item_team_members.count loop
                if p_action_item_team_members(i).id is null then
                    -- id is null? Needs an insert
                    insert into action_item_team_members
                    values p_action_item_team_members(i)
                    returning id into p_action_item_team_members(i).id;
                else
                    -- id is not null, needs an update
                    update action_item_team_members
                    set role = p_action_item_team_members(i).role,
                        user_id = p_action_item_team_members(i).user_id
                    where id = p_action_item_team_members(i).id
                      and action_id = p_action_item_team_members(i).action_id;
                end if;
                -- track which ids we updated and inserted so we can delete others
                l_action_item_member_ids.extend;
                l_action_item_member_ids(l_action_item_member_ids.count)
                    := p_action_item_team_members(i).id;
            end loop;
            -- Delete any existing team members who are not among the updates
            delete from action_item_team_members
            where action_id = p_action_item.id
            and id not in (select column_value
                             from table(l_action_item_member_ids));
        when c_operation_delete then
            delete from action_items
             where id = p_action_item.id;
    end case;
end save;
14.8.2.3.3 保存前后设置默认值并校验#

本节对应官方主题“Defaulting and Validating Pre/Post-Save”。中文学习稿把它放在“集成 API 学习路径”这条主线上理解:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。

阅读时重点跟踪这些对象和概念:REST API、ORDS、JSON 与共享业务逻辑。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.8.2.3.3 保存前后设置默认值并校验”,说明它解决的核心问题是页面和 REST API 共享业务规则、错误消息和事务回滚。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:同一条非法数据无论来自页面还是 API,都会得到一致的校验失败。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop / RESTful Services / SQL Developer Web REST Designer。
  • 操作:根据本节主题“14.8.2.3.3 保存前后设置默认值并校验”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- in package action_items_api
procedure before_save(
    p_action_item  in out action_items%rowtype,
    p_action_item_team_members in out t_action_item_team_members,
    p_operation    in     t_operation)
is
begin
    if p_operation = c_operation_insert then
        -- Providing an ID with insert not allowed
        app_common.report_if_error(
            action_items_common.ensure_null_id_for_new_action(
               p_action_item.id));
    end if;
    if p_operation in (c_operation_insert,c_operation_update) then
        -- Default role to member if not supplied
        for j in 1..p_action_item_team_members.count loop
            if p_action_item_team_members(j).role is null then
                p_action_item_team_members(j).role := 'MEMBER';
            else
                -- Check role value is legal
                app_common.report_if_error(
                    action_items_common.is_valid_role(
                       p_action_item_team_members(j).role));
            end if;
        end loop;
    end if;
end before_save;

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- in package action_items_api
procedure after_save(
    p_action_item              in action_items%rowtype,
    p_action_item_team_members in t_action_item_team_members,
    p_operation                in t_operation)
is
begin
    if p_operation in (c_operation_insert,c_operation_update) then
        app_common.report_if_error(
            action_items_common.no_duplicate_team_members(p_action_item.id));
        app_common.report_if_error(
            action_items_common.one_lead_per_action_team(p_action_item.id));
    end if;
end after_save;
14.8.2.3.4 协调 API 辅助代码#

本节对应官方主题“Coordinating the API Helper Code”。中文学习稿把它放在“集成 API 学习路径”这条主线上理解:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。

阅读时重点跟踪这些对象和概念:REST、JSON、PL/SQL、SQL。对于初学者,不要只记住界面步骤;更重要的是确认外部请求如何进入 ORDS、如何调用 SQL 或 PL/SQL、如何返回 JSON,以及失败时由哪一层给出可诊断的错误。

  • 理解目标:围绕“14.8.2.3.4 协调 API 辅助代码”,说明它解决的核心问题是APEX 内部逻辑如何被整理成可调用、可维护、可保护的集成 API。
  • 定位对象:在 APEX、SQL Developer Web、ORDS 或数据库包中找到本节涉及的模块、模板、handler、SQL、PL/SQL、JSON 或安全配置。
  • 操作路径:先阅读配置或代码,再执行一个最小请求或最小数据变更,确认输入如何进入数据库逻辑并形成响应。
  • 验证结果:能够把本节放回“需求、建模、实现、测试、安全”的完整链路中说明。

学习验证

  • 前提:拥有可实验的 APEX 工作区、示例 Action Items 数据模型,以及调用 ORDS 的测试工具。
  • APEX 区域:SQL Workshop、Object Browser、SQL Commands 与 PL/SQL 包。
  • 操作:根据本节主题“14.8.2.3.4 协调 API 辅助代码”定位对应模块、模板、handler、包或安全配置,先阅读定义,再运行最小请求验证结果。
  • 检查点:把 APEX 应用内部的 PL/SQL 能力整理成外部系统可调用、可验证、可保护的 REST API。
  • 预期结果:能够说明请求入口、数据库逻辑、返回 JSON、错误处理和安全边界之间的关系。

技术示例:以下代码或表格来自捕获源页面,保留原有标识符、URL、HTTP 方法、SQL、PL/SQL 和 JSON 结构;正文解释使用中文,示例本身保持可复制。

源示例 1:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- in package action_items_api
function insert_object(
    p_object in json_object_t)
return json_object_t
is
    l_action_item_rec action_items%rowtype;
    l_action_item_team_members t_action_item_team_members;
begin

action_item_json_to_record
(
        p_object                   => p_object,
        p_action_item              => l_action_item_rec,
        p_action_item_team_members => l_action_item_team_members);

before_save
(l_action_item_rec,l_action_item_team_members,c_operation_insert);

save
(l_action_item_rec,l_action_item_team_members,c_operation_insert);

after_save
(l_action_item_rec,l_action_item_team_members,c_operation_insert);
    return
get_object
(l_action_item_rec.id);
end insert_object;

源示例 2:代码按官方示例保留,便于复制到 SQL Workshop、ORDS Handler 或命令行中核对。

-- in package action_items_api
procedure delete_object(
    p_id in number)
is
    l_action_item_rec action_items%rowtype;
    l_action_item_team_members t_action_item_team_members;
begin
    l_action_item_rec.id := p_id;

before_save
(l_action_item_rec,l_action_item_team_members,c_operation_delete);

save
(l_action_item_rec,l_action_item_team_members,c_operation_delete);

after_save
(l_action_item_rec,l_action_item_team_members,c_operation_delete);
end delete_object;