21

为了检测hstore中是否存在密钥,我需要运行如下查询:

SELECT * FROM tbl WHERE hst ? 'foo'

但是,这给了我一个 PDOException:

PDOException: SQLSTATE[HY093]: Invalid parameter number: no parameters were bound: SELECT * FROM tbl WHERE hst ? 'foo'

有什么办法可以避开问号,这样 PDO 就不会把它当作占位符了?我尝试了最多四个反斜杠和一个双问号 ( ??),但似乎没有什么能说服 PDO 不理会问号。

4

3 回答 3

32

使用函数调用形式。根据系统目录,hstore?操作符使用exist函数:

regress=# select oprname, oprcode from pg_operator where oprname = '?';
 oprname | oprcode 
---------+---------
 ?       | exist
(1 row)

所以你可以写:

SELECT * FROM tbl WHERE exist(hst,'foo');

(我个人不是 hstore 以操作员为中心的设计和文档的忠实粉丝,我认为它丢弃了基于函数的接口的有用的自文档属性而没有任何实际好处,我通常使用它的函数调用而不是它的操作符。只是因为你可以定义运算符并不意味着你应该。)

于 2013-05-01T02:47:20.570 回答
13

在搜索 JSONB 数据时,我遇到了同样的问题。完整的问题在这里

SELECT * FROM post WHERE locations ? :location;

解决方法PostgreSQL 9.5类似:

SELECT * FROM post WHERE jsonb_exists(locations, :location);

我还在PHP bug tracking system 上开了一张票

更新

正如 Diabl0 所提到的,建议的解决方案有效,但不使用索引。经测试:

CREATE INDEX tempidxgin ON post USING GIN (locations);
于 2016-03-23T11:33:22.137 回答
-3

我建议您禁用 PDO 本机准备好的语句,这样问号将被忽略:

$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true);
于 2015-12-22T10:36:23.603 回答