我正在尝试使用Jooq对PostgreSQL数据库进行INSERT。如果String包含带有SQL状态代码的反斜杠字符,则查询失败:42601表示SYNTAX ERROR。
数据库:
CREATE TABLE datahub.test (
body TEXT NOT NULL
);
使用maven生成的Jooq代码:
单元测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/spring-config.xml"})
public class BatchExceptionJooqTest {
private static Logger log = LogManager.getLogger(BatchExceptionJooqTest.class);
@Autowired
private DSLContext db;
@Test
public void runBasicJooqTest(){
try{
final List<InsertQuery<TestRecord>> batchUpdate = Lists.newLinkedList();
InsertQuery<TestRecord> insertQuery = db.insertQuery(TEST);
insertQuery.addValue(TEST.BODY, "It's a bit more complicated than just doing copy and paste... :\\");
batchUpdate.add(insertQuery);
db.batch(batchUpdate).execute();
}catch(Exception e){
log.error(e);
}
}
}
问题
测试失败,但有例外:
2014-12-26 17:11:16,490 [main] ERROR BatchExceptionJooqTest:36:runBasicJooqTest - org.jooq.exception.DataAccessException:SQL [null];批量输入0插入&#34; datahub&#34;。&#34; test&#34; (&#34; body&#34;)值(&#39;它比复制和粘贴更复杂......:\&#39;)已中止。调用getNextException以查看原因。
测试通过,如果不是String:"It's a bit more complicated than just doing copy and paste... :\\"
我使用String:"It's a bit more complicated than just doing copy and paste... :\\\\"
。与操作期间单引号发生的情况相比,这似乎有点不一致。它正确加倍,以便通过SQL解析器。反斜杠不是这样。
我读到某个地方,用另一个反斜杠转义反斜杠不是SQL标准的一部分,Postgre最近改变了它的默认行为。但是我不清楚manual p 4.1.2.2的含义 - 它似乎表明双反斜杠应该有效,并且没有任何理由让jooq不这样做。
所以..有人可以解释一下Jooq中描述的情况:
谢谢
答案 0 :(得分:1)
您正在使用PostgreSQL 8.x.在该版本中,即使没有前面的E
,系统也默认接受反斜杠转义字符串文字。
为避免这种情况,您应将服务器配置变量standard_conforming_strings
设置为ON
。
当然,强烈建议您迁移到高于8.x的PostgreSQL版本,因为8.x版本已达到使用寿命并且不再受支持。
答案 1 :(得分:0)
jOOQ 3.5引入了org.jooq.conf.Settings.backslashEscaping
(https://github.com/jOOQ/jOOQ/issues/3000)。这主要是针对MySQL引入的,今天仍默认使用反斜杠转义为非标准的字符串文字转义。
请注意,此设置仅影响内联绑定值,因此在将值绑定到PreparedStatement
时,它不会转义反斜杠。
我同意RealSkeptic's answer,它建议您更改数据库行为或升级到较新的PostgreSQL版本。