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

H2数据库JSON_TABLE别名创建失败,请求技术支持

解决H2数据库创建JSON_TABLE别名的编译错误

问题背景

为编写单元测试,尝试给H2数据库的JSON_TABLE命令创建别名,但执行时出现编译错误。原创建别名的SQL代码如下:

DROP ALIAS if exists JSON_TABLE;
CREATE ALIAS IF NOT EXISTS JSON_TABLE AS '
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.h2.tools.SimpleResultSet;
import org.json.JSONArray;
import org.json.JSONObject;
import java.lang.String;
java.sql.ResultSet jsonTable(java.lang.String json, java.lang.String key) throws java.sql.SQLException {
    org.h2.tools.SimpleResultSet rs = new org.h2.tools.SimpleResultSet();
    rs.addColumn("FIELD", Types.VARCHAR, 255, 0);
    rs.addColumn("OLD_VALUE", Types.VARCHAR, 255, 0);
    rs.addColumn("NEW_VALUE", Types.VARCHAR, 255, 0);

    org.json.JSONArray jsonArray = new org.json.JSONArray(json);
    for (int i = 0; i < jsonArray.length(); i++) {
        org.json.JSONObject obj = jsonArray.getJSONObject(i);
        rs.addRow(
            obj.optString("field", null),
            obj.optString("oldValue", null),
            obj.optString("newValue", null)
        );
    }
    return rs;
}';

使用该别名的视图定义:

CREATE OR REPLACE VIEW dummy.V AS
SELECT ROWNUM        AS ID,
       a.changed_at  AS "CHANGED_AT",
       a.changed_by  AS "CHANGED_BY",
       a.object_id   AS "OBJECT_ID",
       a.order_id    AS "ORDER_ID",
       a.order_type  AS "ORDER_TYPE",
       a.object_type AS "OBJECT_TYPE",
       a.action      AS "ACTION",
       a.task_id     AS "TASK_ID",
       jt.FIELD      AS FIELD,
       jt.OLD_VALUE  AS OLD_VALUE,
       jt.NEW_VALUE  AS NEW_VALUE
FROM dummy.Table a,
     json_table(
             a.changes, '$[*]'
         COLUMNS (
             FIELD VARCHAR2(255 CHAR) PATH '$.field',
             OLD_VALUE VARCHAR2(255 CHAR) PATH '$.oldValue',
             NEW_VALUE VARCHAR2(255 CHAR) PATH '$.newValue'
             )
     ) jt

报错核心信息:

/org/h2/dynamic/JSON_TABLE.java:7: error: illegal start of type
import java.sql.ResultSet;
^
/org/h2/dynamic/JSON_TABLE.java:7: error: <identifier> expected
import java.sql.ResultSet;
                 ^
...(共14个类似编译错误)

错误原因

H2数据库的CREATE ALIAS要求提供的Java代码必须是完整的类定义,不能直接写import语句和独立方法。H2会将这段代码编译成一个Java类,原代码缺少类包裹,导致编译器无法识别语法结构。

修复方案

1. 修正别名创建SQL

将Java代码包裹在一个类中,同时调整引号转义(把&quot;替换为",并在SQL中用单引号转义),修正后的代码如下:

DROP ALIAS IF EXISTS JSON_TABLE;
CREATE ALIAS IF NOT EXISTS JSON_TABLE AS '
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.h2.tools.SimpleResultSet;
import org.json.JSONArray;
import org.json.JSONObject;

public class JsonTableFunction {
    public static ResultSet jsonTable(String json) throws SQLException {
        SimpleResultSet rs = new SimpleResultSet();
        rs.addColumn("FIELD", Types.VARCHAR, 255, 0);
        rs.addColumn("OLD_VALUE", Types.VARCHAR, 255, 0);
        rs.addColumn("NEW_VALUE", Types.VARCHAR, 255, 0);

        JSONArray jsonArray = new JSONArray(json);
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject obj = jsonArray.getJSONObject(i);
            rs.addRow(
                obj.optString("field", null),
                obj.optString("oldValue", null),
                obj.optString("newValue", null)
            );
        }
        return rs;
    }
}';

2. 适配视图调用

由于当前实现只接受JSON字符串参数(无法解析标准JSON_TABLE的路径和列定义语法),需要调整视图的调用方式:

CREATE OR REPLACE VIEW dummy.V AS
SELECT ROWNUM        AS ID,
       a.changed_at  AS "CHANGED_AT",
       a.changed_by  AS "CHANGED_BY",
       a.object_id   AS "OBJECT_ID",
       a.order_id    AS "ORDER_ID",
       a.order_type  AS "ORDER_TYPE",
       a.object_type AS "OBJECT_TYPE",
       a.action      AS "ACTION",
       a.task_id     AS "TASK_ID",
       jt.FIELD      AS FIELD,
       jt.OLD_VALUE  AS OLD_VALUE,
       jt.NEW_VALUE  AS NEW_VALUE
FROM dummy.Table a,
     TABLE(JSON_TABLE(a.changes)) jt

3. 额外说明

如果需要完全兼容标准JSON_TABLE的语法(支持路径和列定义),需要更复杂的实现:

  • 解析第二个参数中的JSON路径表达式
  • 解析COLUMNS子句中的列定义和路径
  • 动态生成结果集的列和数据

但上述修复已经解决了编译错误,满足基础的JSON数组展开需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 19:24:58