Is there anything in the JDBC spec which allows a ? to be escaped and be anything other than a parameter placeholder?
例如,Postgres允许您使用?作为运算符:
SELECT * FROM tbl WHERE tbl.data ? 'abc'
可以使用JDBC驱动程序吗?作为操作符仍然符合JDBC标准?
解决方法
所以我的建议是提供某种逃脱(或替代运算符).然而,查看JDBC规范时,驱动程序只应使用JDBC转义语法来实现JDBC规范中定义的转义(13.4.2:“转义语法不用于调用用户定义或供应商特定的标量函数. “;虽然这是关于{fn …}的转义).
所以你需要使用一个替代的逃脱,或者“打破”规则(我不认为任何人会介意).如果你想要一个更有创意的答案,你可以把你的问题发送到jdbc-spec-discuss mailinglist.我相信Lance Andersen(JDBC spec lead)将提供一个答案.
编辑:
还有趣的是,JDBC规范第6.2节(指南和要求)说:
Drivers should provide access to every feature implemented by the underlying data source,including features that extend the JDBC API. The intent is for applications using the JDBC API to have access to the same feature set as native applications.
所以基于这一点,你应该(不一定)支持?操作者,你只需要找到一个实用的方法.
基于discussion on jdbc-spec-discuss更新
根据Lance Andersen,JDBC规范遵循关于问号的sql规范:它们只能用作查询文本中的参数占位符(除了当然在注释和引用的文本中),因为这样使用?如Postgresql中的hstore操作符不允许. (见this message)
可用的选项是为操作符提供别名或逃脱,只要这不会与未来的变化相冲突(这在没有透视的情况下相当困难).最好的解决方案 – 防止未来JDBC更改的问题 – 可能是一个自定义的转义.
JDBC实际上并没有定义供应商的转义,但是Lance Andersen确实提出了类似于JDBC转义的转义:{postgres<要转义的东西>};在此转义中使用vendorname或drivername将提供一种命名空间的形式,以防止与规范的冲突. (见this message)
为了符合’正常’JDBC函数转义,我建议定义一个允许您的问题中的查询被声明为:
SELECT * FROM tbl WHERE {postgres containskey(tbl.data,'abc')}
我根据含义选择了includekey?在hstore documentation?类似的建议?& :containsallkeys)和for?| :containsanykey.为了保持一致性,您可以考虑为其他hstore运算符这样做.
你也可以决定只逃避问号本身.例如,使用{postgres’?’}或{postgres qm}(qm作为问号).我认为可读性小于我的功能逃避建议:
SELECT * FROM tbl WHERE tbl.data {postgres '?'} 'abc'