如何防止PDO将问号解释为占位符?

时间:2013-05-01 02:33:11

标签: php postgresql pdo

为了检测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单独留下问号。

3 个答案:

答案 0 :(得分:28)

使用函数调用表单。根据系统目录,hstore ?运算符使用exist函数:

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

所以你可以写:

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

(就个人而言,我不是hstore以运营商为中心的设计和文档的忠实粉丝,我认为它丢弃了基于函数的界面的有用的自我文档属性而没有任何实际好处,我通常使用它的函数调用而不是它的运营商。仅仅因为你可以定义运算符并不意味着你应该这样做。)

答案 1 :(得分:8)

在搜索JSONB数据时遇到了同样的问题。完整的问题是here

SELECT * FROM post WHERE locations ? :location;

PostgreSQL 9.5上的解决方法类似:

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

我还在PHP错误跟踪系统

上打开了ticket

更新

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

CREATE INDEX tempidxgin ON post USING GIN (locations);

答案 2 :(得分:-3)

我建议您禁用PDO本机预准备语句,以便忽略问号:

$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true);