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

如何使用Apache Calcite Planner正确定义与设置SQL参数?

问题原因

直接将转换后的RelNode传给RelRunners.run()生成的PreparedStatement没有保留参数元数据——RelNode仅代表执行计划的逻辑结构,不存储参数的位置、类型等定义,导致调用setLong()时找不到对应参数。

正确处理流程

Calcite的Planner提供了prepare()方法专门处理参数化查询,该方法会生成包含参数元数据的RelPreparedStatement,基于它创建的JDBC PreparedStatement才能正确识别并绑定参数。

修改后的完整代码:

// custom config
FrameworkConfig frameworkConfig = Frameworks.newConfigBuilder()
        .parserConfig(parserConfig)
        .defaultSchema(rootSchema)
        .sqlToRelConverterConfig(convertConfig)
        .operatorTable(operatorTable)
        .build();

Planner planner = Frameworks.getPlanner(frameworkConfig);

String sql = "Select id, name from t where id in (?, ?)";
SqlNode parsedSqlNode = planner.parse(sql);
SqlNode validatedSqlNode = planner.validate(parsedSqlNode);
// 使用planner.prepare处理参数化查询,生成带参数元数据的RelPreparedStatement
RelPreparedStatement relPreparedStmt = planner.prepare(validatedSqlNode);
PreparedStatement preparedStatement = RelRunners.run(relPreparedStmt);

preparedStatement.setLong(1, 11111);
preparedStatement.setLong(2, 22222);

ResultSet resultSet = preparedStatement.executeQuery();
// ....
额外说明
  • 若需自定义参数类型,可在parserConfig中配置SqlParser.Config的参数类型映射,或在验证阶段通过SqlValidator上下文指定参数类型
  • 确保表t的id字段类型与setLong()的类型匹配,避免类型转换错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 01:25:18