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

Ignite三个缓存UNION ALL联合查询报错及正确实现方式问询

问题原因

你遇到的报错由两个核心问题导致:

  • 跨缓存查询的schema引用规则错误:Ignite中每个开启了SQL功能的缓存,默认对应的SQL schema名称就是缓存自身的名称。如果缓存名包含小写字符、特殊符号,SQL解析时会默认将未加引号的标识符转为全大写,导致和实际缓存名匹配失败,触发schema不存在的报错。
  • SQL语法缺失:你写的查询逻辑中,第二个SELECT语句和第三个SELECT语句之间漏写了UNION ALL关键字,也会导致SQL解析失败。
正确实现方式

前置校验

首先要确保三个缓存创建时都开启了SQL功能,也就是对应的CacheConfiguration中已经通过setIndexedTypes注册了对应的实体类(ConfirmedEvent、UnconfirmedEvent)。

修正后的代码实现

// 先生成三个缓存的实际名称
String confirmedCacheName = String.format(CONFIRMED_EVENT_CACHE, mcId);
String nonUrgentCacheName = String.format(UNCONFIRMED_NON_URGENT_EVENT_CACHE, mcId);
String urgentCacheName = String.format(UNCONFIRMED_URGENT_EVENT_CACHE, mcId);
int afibType = AnnotationConverter.StringToRhythmValue(AFIB);

// 构造SQL,缓存名用双引号包裹避免大小写转换,补全缺失的UNION ALL
String EVENT_GET_RHYTHM_BY_ID = "SELECT timestamp FROM ConfirmedEvent " +
        "WHERE orderId = ? AND startTime < ? AND endTime > ? AND type = ? " +
        "UNION ALL " +
        "SELECT timestamp FROM \"" + nonUrgentCacheName + "\".UnconfirmedEvent " +
        "WHERE orderId = ? AND startTime < ? AND endTime > ? AND type = ? " +
        "UNION ALL " +
        "SELECT timestamp FROM \"" + urgentCacheName + "\".UnconfirmedEvent " +
        "WHERE orderId = ? AND startTime < ? AND endTime > ? AND type = ? " +
        "ORDER BY startTime";

// 传递查询参数,按SQL中占位符的顺序依次传入即可
SqlFieldsQuery sql_Afib = new SqlFieldsQuery(EVENT_GET_RHYTHM_BY_ID)
        .setArgs(
                // 第一个SELECT的参数
                orderId, endTimestamp, startTimestamp, afibType,
                // 第二个SELECT的参数
                orderId, endTimestamp, startTimestamp, afibType,
                // 第三个SELECT的参数
                orderId, endTimestamp, startTimestamp, afibType
        );

List<Long> EventsEndTime = new ArrayList<>();
// 用任意一个同实例下的缓存执行查询都可以,不需要和SQL里的表绑定
try (QueryCursor<List<?>> cursor = confirmedEventCache.query(sql_Afib)) {
    for (List<?> row : cursor) {
        EventsEndTime.add((Long) row.get(0));
    }
}
补充注意事项
  • 如果你创建缓存时通过setSqlSchema自定义了schema名称,直接用自定义的schema名代替上面代码中的缓存名即可。
  • 所有可变查询条件都通过setArgs传递,不要用String.format拼接,避免SQL注入风险。
  • 三个缓存必须属于同一个Ignite实例,且执行查询时都处于活跃状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 05:09:03