Jooq / PostgreSQL INSERT子句中的反斜杠

时间:2014-12-26 15:34:03

标签: java postgresql jooq

我正在尝试使用Jooq对PostgreSQL数据库进行INSERT。如果String包含带有SQL状态代码的反斜杠字符,则查询失败:42601表示SYNTAX ERROR。

  • Jooq:3.4.4
  • postgresql驱动程序:8.4-702.jdbc4
  • PostgreSQL:" PostgreSQL x86_64-redhat-linux-gnu上的8.4.20,由GCC gcc(GCC)4.4.7 20120313(Red Hat 4.4.7-4)编译,64位"
  • JDK 1.8.0_25
  • Spring Tool Suite 3.6.0.RELEASE

数据库:

CREATE TABLE datahub.test (
    body TEXT NOT NULL
);

使用maven生成的Jooq代码:

  • jooq-codegen-maven version 3.4.4
  • generator.name:org.jooq.util.DefaultGenerator
  • generator.database.name:org.jooq.util.postgres.PostgresDatabase

单元测试

@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中描述的情况:

  1. 除了将我的应用程序正在处理的所有传入反斜杠加倍之外,还没有解决方法吗?
  2. 是否有所需的行为,但我可以做一些配置更改,以使Jooq以类似于单引号的方式处理反斜杠?
  3. 这是一个错误吗?
  4. 我做错了什么?
  5. 谢谢

2 个答案:

答案 0 :(得分:1)

您正在使用PostgreSQL 8.x.在该版本中,即使没有前面的E,系统也默认接受反斜杠转义字符串文字。

为避免这种情况,您应将服务器配置变量standard_conforming_strings设置为ON

当然,强烈建议您迁移到高于8.x的PostgreSQL版本,因为8.x版本已达到使用寿命并且不再受支持。

答案 1 :(得分:0)

jOOQ 3.5引入了org.jooq.conf.Settings.backslashEscapinghttps://github.com/jOOQ/jOOQ/issues/3000)。这主要是针对MySQL引入的,今天仍默认使用反斜杠转义为非标准的字符串文字转义。

请注意,此设置仅影响内联绑定值,因此在将值绑定到PreparedStatement时,它不会转义反斜杠。

我同意RealSkeptic's answer,它建议您更改数据库行为或升级到较新的PostgreSQL版本。