H2数据库NON_KEYWORDS参数为何在SQL查询中被忽略?
问题原因及解决办法
核心原因
连接参数未全局生效
Spring的EmbeddedDatabaseBuilder若仅简单设置URL参数,后续从数据源获取的查询连接可能未继承该配置。默认嵌入式数据源实现创建新连接时,可能未复用包含NON_KEYWORDS=OFFSET的完整URL。未启用Oracle兼容模式
H2的关键字列表随SQL模式变化,若未设置MODE=ORACLE,即便添加NON_KEYWORDS=OFFSET,H2仍可能在默认模式下将OFFSET解析为分页关键字,引发语法冲突。初始化脚本与查询连接的上下文差异
初始化脚本执行时直接使用创建数据源的初始连接,该连接已加载NON_KEYWORDS配置;但后续查询用的连接可能来自内部连接池,未正确加载参数。
解决步骤
1. 确保连接URL包含完整参数(推荐)
在EmbeddedDatabaseBuilder中,将MODE=ORACLE和NON_KEYWORDS=OFFSET合并到数据库名称/URL中,保证所有连接复用同一配置:
EmbeddedDatabase db = new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.H2) .setName("mydb;MODE=ORACLE;NON_KEYWORDS=OFFSET") .addScript("classpath:init-mytbl.sql") .build();
2. 在初始化脚本中全局设置非关键字
若URL参数方式仍不生效,可在初始化SQL脚本开头添加H2全局设置语句,强制标记OFFSET为非关键字:
SET NON_KEYWORDS = OFFSET; CREATE TABLE mytbl ( id INT, offset INT );
3. 验证连接池配置(若存在)
如果测试代码使用了连接池(如Spring默认内置池),需确认连接池创建新连接时复用了带参数的URL,而非生成默认URL。
额外说明
H2 2.1.x版本中NON_KEYWORDS参数对大小写不敏感,但需确保拼写准确;启用MODE=ORACLE不仅能解决关键字冲突,还能让H2语法、函数更贴近Oracle,减少其他兼容性问题。
内容的提问来源于stack exchange,提问作者Kap4Lin
相关产品推荐
相关产品推荐

