You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle 19C中如何比较JSON_OBJECT_T?JSON_EQUAL报错解决

在Oracle 19C PL/SQL中比较JSON_OBJECT_T对象的方法

Oracle 19C并未内置JSON_EQUAL函数,这是你遇到PLS-00201错误的原因。以下是几种可行的实现方案,包含高效的内置函数用法和自定义比较逻辑:

一、高效方案:使用DBMS_JSON.COMPARE内置函数

Oracle 12.2及以上版本(含19C)提供了DBMS_JSON包,其中的COMPARE函数可用于比较JSON数据的内容相等性,会忽略JSON对象的键顺序,完全符合JSON规范的相等判定逻辑,且性能远高于自定义函数。

实现代码

CREATE OR REPLACE FUNCTION json_obj_equal(p_obj1 JSON_OBJECT_T, p_obj2 JSON_OBJECT_T) RETURN BOOLEAN IS
BEGIN
  -- COMPARE返回0表示两个JSON内容完全相等
  RETURN DBMS_JSON.COMPARE(p_obj1.to_clob(), p_obj2.to_clob()) = 0;
EXCEPTION
  WHEN OTHERS THEN
    -- 出现异常时判定为不相等
    RETURN FALSE;
END;
/

使用示例

DECLARE
  rec1 JSON_OBJECT_T := JSON_OBJECT_T('{"id":1,"name":"Alice"}');
  api_rec JSON_OBJECT_T := JSON_OBJECT_T('{"name":"Alice","id":1}'); -- 键顺序不同
BEGIN
  IF json_obj_equal(rec1, api_rec) THEN
    DBMS_OUTPUT.PUT_LINE('两个JSON对象相等');
  ELSE
    DBMS_OUTPUT.PUT_LINE('两个JSON对象不相等');
  END IF;
END;
/

输出结果为两个JSON对象相等,符合预期。

二、自定义递归比较函数(处理复杂嵌套场景)

如果你的JSON对象包含嵌套的对象或数组,且需要更精细的控制逻辑,可以自定义递归函数遍历键值对进行比较:

1. 对象比较函数

CREATE OR REPLACE FUNCTION json_obj_equal(p_obj1 JSON_OBJECT_T, p_obj2 JSON_OBJECT_T) RETURN BOOLEAN IS
  l_keys1 JSON_KEY_LIST;
BEGIN
  -- 先比较键的数量
  IF p_obj1.get_size() != p_obj2.get_size() THEN
    RETURN FALSE;
  END IF;

  l_keys1 := p_obj1.get_keys();
  -- 遍历每个键,逐一比较对应值
  FOR i IN 1..l_keys1.COUNT LOOP
    -- 检查键是否存在于另一个对象
    IF NOT p_obj2.has(l_keys1(i)) THEN
      RETURN FALSE;
    END IF;

    DECLARE
      l_val1 JSON_ELEMENT_T := p_obj1.get(l_keys1(i));
      l_val2 JSON_ELEMENT_T := p_obj2.get(l_keys1(i));
    BEGIN
      -- 嵌套对象递归比较
      IF l_val1.is_object() AND l_val2.is_object() THEN
        IF NOT json_obj_equal(JSON_OBJECT_T(l_val1), JSON_OBJECT_T(l_val2)) THEN
          RETURN FALSE;
        END IF;
      -- 嵌套数组递归比较
      ELSIF l_val1.is_array() AND l_val2.is_array() THEN
        IF NOT json_arr_equal(JSON_ARRAY_T(l_val1), JSON_ARRAY_T(l_val2)) THEN
          RETURN FALSE;
        END IF;
      -- 基础类型直接比较字符串形式
      ELSIF l_val1.to_string() != l_val2.to_string() THEN
        RETURN FALSE;
      END IF;
    END;
  END LOOP;

  RETURN TRUE;
EXCEPTION
  WHEN OTHERS THEN
    RETURN FALSE;
END;
/

2. 数组比较辅助函数

CREATE OR REPLACE FUNCTION json_arr_equal(p_arr1 JSON_ARRAY_T, p_arr2 JSON_ARRAY_T) RETURN BOOLEAN IS
BEGIN
  -- 先比较数组长度
  IF p_arr1.get_size() != p_arr2.get_size() THEN
    RETURN FALSE;
  END IF;

  -- 遍历数组元素逐一比较
  FOR i IN 0..p_arr1.get_size()-1 LOOP
    DECLARE
      l_elem1 JSON_ELEMENT_T := p_arr1.get(i);
      l_elem2 JSON_ELEMENT_T := p_arr2.get(i);
    BEGIN
      IF l_elem1.is_object() AND l_elem2.is_object() THEN
        IF NOT json_obj_equal(JSON_OBJECT_T(l_elem1), JSON_OBJECT_T(l_elem2)) THEN
          RETURN FALSE;
        END IF;
      ELSIF l_elem1.is_array() AND l_elem2.is_array() THEN
        IF NOT json_arr_equal(JSON_ARRAY_T(l_elem1), JSON_ARRAY_T(l_elem2)) THEN
          RETURN FALSE;
        END IF;
      ELSIF l_elem1.to_string() != l_elem2.to_string() THEN
        RETURN FALSE;
      END IF;
    END;
  END LOOP;

  RETURN TRUE;
EXCEPTION
  WHEN OTHERS THEN
    RETURN FALSE;
END;
/

三、方案选择建议

  • 优先使用DBMS_JSON.COMPARE:内置函数性能最优,且自动处理键顺序、嵌套结构等问题,适合绝大多数场景。
  • 自定义函数仅用于特殊需求:比如需要忽略某些特定键、自定义值比较逻辑等场景。
  • 避免直接比较字符串:除非能确保两个JSON对象的键顺序完全一致,否则字符串比较会误判键顺序不同但内容相同的JSON对象。

内容的提问来源于stack exchange,提问作者Nishan Karki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 08:13:15