逃脱的正确方法是啥?使用 Oracle 12c MATCH_RECOGNIZE 时 JDBC PreparedStatement 中的字符?

Posted

技术标签:

【中文标题】逃脱的正确方法是啥?使用 Oracle 12c MATCH_RECOGNIZE 时 JDBC PreparedStatement 中的字符?【英文标题】:What's the correct way to escape the ? character in a JDBC PreparedStatement when using Oracle 12c MATCH_RECOGNIZE?逃脱的正确方法是什么?使用 Oracle 12c MATCH_RECOGNIZE 时 JDBC PreparedStatement 中的字符? 【发布时间】:2017-02-08 08:37:12 【问题描述】:

以下查询在 Oracle 12c 中是正确的:

SELECT *
FROM dual
MATCH_RECOGNIZE (
  MEASURES a.dummy AS dummy
  PATTERN (a?)
  DEFINE a AS (1 = 1)
)

但它不能通过 JDBC 工作,因为 ? 字符用作正则表达式字符,而不是用作绑定变量。

假设我想通过绑定变量将 PreparedStatement 作为 PreparedStatement 运行,通过 JDBC 转义 ? 的正确方法是什么?

注意:

我在 JDBC 规范的讨论邮件列表中找到了一个讨论,但对这个问题没有结论:http://mail.openjdk.java.net/pipermail/jdbc-spec-discuss/2013-October/000066.html PostgreSQL 与 JSON 运算符有类似问题:How do I use PostgreSQL JSON(B) operators containing a question mark "?" via JDBC

【问题讨论】:

不要使用PreparedStatement? @a_horse_with_no_name:假设我有一个超级复杂的派生表,而不是dual,其中包含大量绑定变量,因为 SQL 注入等。 【参考方案1】:

这在the documentation 中有明确的说明:

MATCH_RECOGNIZE子句

? 字符在 Oracle 数据库 11g 及更高版本的MATCH_RECOGNIZE 子句中用作标记。由于JDBC标准将?字符定义为参数标记,JDBC Driver和Server SQL Engine无法区分同一个token的不同用途。

在早期版本的 JDBC 驱动程序中,如果要将 ? 字符解释为 MATCH_RECOGNIZE 标记而不是参数标记,则必须使用 Statement 而不是 PreparedStatement 并禁用转义加工。但是,从 Oracle Database 12c 第 1 版 (12.1.0.2) 开始,您可以在使用 ? 字符的同时使用 '\ ... \' 语法,这样 JDBC 驱动程序就不会将其作为参数标记进行处理,并允许 SQL 引擎处理它。

【讨论】:

如果要将转义序列放入 Java 字符串中,则需要对 Java 字符串中的 \ 字符进行转义,以便完整序列为 \\?\\。这在OJDBC documentation 中更清楚。

以上是关于逃脱的正确方法是啥?使用 Oracle 12c MATCH_RECOGNIZE 时 JDBC PreparedStatement 中的字符?的主要内容,如果未能解决你的问题,请参考以下文章

ORACLE 12C PDBORCL的开启方法

使用 c# 和 OCI 中的 RETURNING INTO 子句在 Oracle 上创建行 ID 的正确方法是啥:

使用 sequelize N:M 关联实现“平坦”结果的“正确”方法是啥

ORACLE12C PDB创建默认表空间和用户语句

如何在 Oracle 12c 中创建带条件的索引?

RedHat7.2安装oracle 12c