【问题标题】:How to escape single quotes while creating a query string with jooq?如何在使用 jooq 创建查询字符串时转义单引号?
【发布时间】:2017-07-01 04:19:31
【问题描述】:

我正在尝试通过以下方式创建一个 jooq 查询字符串

DSL.using(SQLDialect.MYSQL)
            .select(
                    ImmutableList.of(DSL.field("Name"))
            .from(DSL.table("Account"))
            .where(DSL.field("Name").eq("Yaswanth's Company"))).toString()

生成的查询字符串将单引号用另一个单引号转义,这是 mySQL 转义单引号的默认方式。

"select Name from Account where Name = 'Yaswanth''s Company'"

但我需要用反斜杠转义单引号,因为我正在为 salesforce 形成查询字符串。 (称为 SOQL)。

我需要这样的查询字符串

"select Name from Account where Name = 'Yaswanth\\'s Company'"

我查看了 jooq 库代码,这是在 DefaultBinding 类中硬编码的

private final String escape(Object val, Context<?> context) {
    String result = val.toString();

    if (needsBackslashEscaping(context.configuration()))
        result = result.replace("\\", "\\\\");

    return result.replace("'", "''");
}

我有没有办法通过 DSL.using(*, *) 可以传递的配置或设置来覆盖此默认行为?

【问题讨论】:

    标签: java sql jooq


    【解决方案1】:

    大多数 SQL 数据库都遵循将单引号加倍以进行转义的 SQL 标准,但使此功能可配置当然是有意义的。我们可能会使用#5873 为 jOOQ 3.10 执行此操作。

    同时,最好的解决方法是为所有 String 类型编写自己的 data type binding,并在生成 SQL 字符串时覆盖 DefaultBinding 行为。类似这样的东西:

    代码生成配置

    使用&lt;forcedTypes/&gt;

    <forcedType>
        <userType>java.lang.String</userType>
        <binding>com.example.AlternativeEscapingStringBinding</binding>
        <!-- add other vendor-specific string type names here -->
        <types>(?i:N?(VAR)?CHAR|TEXT|N?CLOB)</types>
    </forcedType>
    

    数据类型绑定

    public class AlternativeEscapingStringBinding implements Binding<String, String> {
        ...
    
        @Override
        public void sql(BindingSQLContext<String> ctx) throws SQLException {
            if (ctx.paramType() == ParamType.INLINED) 
                if (ctx.value() == null)
                    ctx.render().sql('null');
                else
                    ctx.render()
                       .sql('\'')
                       .sql(ctx.value().replace("'", "\\'"))
                       .sql('\'');
            else
                ctx.render().sql('?');
        }
    }
    

    如果您不使用代码生成器

    您仍然可以将自己的数据类型绑定手动应用于您的字段:

    DSL.field("Name", SQLDataType.VARCHAR
                                 .asConvertedDataType(new AlternativeEscapingStringBinding()));
    

    你只需要每次都记住这一点......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-12
      • 2023-04-02
      • 2017-07-10
      • 2021-04-14
      • 2022-01-27
      相关资源
      最近更新 更多