JDBC规范中是否有任何允许对“?”进行转义并使其成为除参数占位符之外其他内容的内容?
例如,Postgres允许您将?
用作运算符:
SELECT * FROM tbl WHERE tbl.data ? 'abc'
如果使用 ? 作为运算符的JDBC驱动程序,是否仍然符合JDBC标准?
JDBC规范中是否有任何允许对“?”进行转义并使其成为除参数占位符之外其他内容的内容?
例如,Postgres允许您将?
用作运算符:
SELECT * FROM tbl WHERE tbl.data ? 'abc'
如果使用 ? 作为运算符的JDBC驱动程序,是否仍然符合JDBC标准?
如果您拥有最新的PostgreSQL驱动程序,则可以使用:
??
修改原查询:
SELECT * FROM tbl WHERE tbl.data ?? 'abc'
具体细节在此拉取请求中 - https://github.com/pgjdbc/pgjdbc/pull/227 虽然这个更改是在最初的问题之后很长时间才进行的,但值得注意的是现在有一个简单的答案。
{fn ...}
转义的)。驱动程序应提供对底层数据源实现的每个功能的访问,包括扩展JDBC API的功能。其目的是使使用JDBC API的应用程序能够访问与本地应用程序相同的功能集。
因此,基于这一点,您应该(并非必须)支持?
运算符,您只需要找到一种实用的方法来做到这一点。
根据Lance Andersen的说法,JDBC规范遵循SQL规范关于问号的使用:它们只能作为查询文本中的参数占位符使用(当然除了注释和引用文本),因此像PostgreSQL hstore运算符中使用?
是不被允许的。 (请参见此消息)
可选的方法是提供运算符别名或转义,前提是这不会与未来的更改冲突(这很难在没有预知能力的情况下做到)。最好的解决方案-为了防止未来JDBC更改出现问题-可能是自定义转义。
JDBC实际上并没有定义供应商转义,但Lance Andersen建议使用类似于JDBC转义的转义:{postgres <thing to be escaped>}
;在此转义中使用供应商名称或驱动程序名称将提供一种命名空间形式,应该可以防止与规范冲突(参见this message)。SELECT * FROM tbl WHERE {postgres containskey(tbl.data, 'abc')}
containskey
是基于hstore文档中?
的含义。类似的建议对于?&
为containsallkeys
,对于?|
为containsanykey
。为了一致性,您也可以考虑对其他hstore运算符进行此操作。{postgres '?'}
或{postgres qm}
(qm代表问号)。我认为可读性不及我的函数转义建议:SELECT * FROM tbl WHERE tbl.data {postgres '?'} 'abc'
下一个JDBC规范(可能编号为4.4),将可能添加一个明确的JDBC转义来完全转义查询的片段,旨在能够转义问号,以便支持不原生使用问号作为参数标记并需要支持问号的其他用途的数据库系统。
建议的语法将是{\ <thing-to escape> \}
(Oracle JDBC驱动程序已支持作为非标准转义)。使用此语法,然后可以使用{\?\}
转义参数标记(在字符串文字中:{\\?\\}
),或转义更大的片段以提高可读性。
另请参见SQL 2016 MATCH RECOGNIZE JDBC parameter Marker / Escape Characters和jdbc-spec-discuss邮件列表上的早期讨论。
?
的内容。它关于?
的描述如下:?
的特性:?
的驱动程序是否在技术上符合规范,但它可能不太兼容。?
的方法不检查任何转义字符。
1. JDBC 4.1规范,第13.2节 —— PreparedStatement
接口
2. JDBC 4.1规范,第13.3.2节 —— 设置参数
3. JDBC 4.1规范,第13.4节 —— 转义语法
c {?} 'foo'
?)。正如aymeric的答案中指出的那样,已经有一种使用JDBC的解决方法。 - mattsexists
不使用索引) - Mark Rotteveel