对于以下SQL,我将得到‘基数违规’错误:
原则\DBAL\ exception \DriverException:在执行过程中发生异常
SELECT p.* FROM mod_products_products p
LEFT JOIN mod_products_products_categories c_link ON c_link.product_id = p.id
LEFT JOIN mod_products_brands b ON p.brand_id = b.id
LEFT JOIN mod_products_groups vg ON p.variation_id = vg.id
LEFT JOIN mod_products_categories c ON c_link.category_id = c.id
LEFT JOIN mod_products_group_options vg_o ON vg_o.group_id = vg.id
LEFT JOIN mod_products_group_values vg_o_v ON vg_o_v.option_id = vg_o.id
WHERE (p.name LIKE (?, ?)) AND (p.parent_id = 0) AND (vg_o.disabled=0)
GROUP BY p.id ORDER BY p.name ASC
LIMIT 18446744073709551615 OFFSET 0对于params "%big%","%light%":SQLSTATE21000:基数违反: 1241操作数应该包含1列(S)。
只有在WHERE (p.name LIKE (?, ?))的参数列表中定义了多个值时,才会发生错误。
我使用executeQuery(),并将数组作为Connection::PARAM_STR_ARRAY传递。在最初的声明中,我将问题点定义为:
$builder->andWhere('p.name LIKE (:partial_names)');似乎不喜欢将数组作为partial_names传递。对造成这种情况的原因有何看法,以及如何避免?
发布于 2016-06-23 13:36:43
类似于MySQL是一个“字符串比较函数”,因此使用“简单模式匹配”将一个字符串与另一个字符串进行比较。
如果您检查SQL标准,您会注意到LIKE只接受“类字符”和“类似八进制”的参数,这两个参数本质上都是我们所称的字符串。( LIKE在RHS上执行二进制字符对字符匹配,这与=的操作方式不同,这一点有一些细节:foo LIKE 'bar'和foo='bar'可能产生不同的结果。)
所有这一切都意味着您不能执行LIKE ('a', 'b'),因为列式表达式('a', 'b')不是字符串样的。或者在古怪的标准语言中,它的基数(2)不同于预期的基数(1)。但是,您可以在MySQL和SQLite (可能是其他引擎)中这样做:
WHERE foo LIKE ('%bar')因为RHS的基数是1(只有一列),这正是LIKE所期望的。
您需要一些与foo LIKE IN ('a', 'b')类似的东西,但这一点也不存在(因为上面提到的SQL标准原因)。这个问答给出了一些解决该行为的方法,基于REGEXP的是可接受的答案。
因此,为了避免这个错误,您需要重写查询,以使用多个LIKE、一个REGEXP,甚至类似于FIND_IN_SET之类的东西。
发布于 2016-06-24 15:56:59
变化
(p.name LIKE (?, ?))至
(p.name LIKE ? OR p.name LIKE ?)和
["%big%", "%light%"]至
"%big%", "%light%"https://stackoverflow.com/questions/37786370
复制相似问题