DBAL基数违规错误

问题描述:

我得到了 '基数违规' 的错误,以下SQL:DBAL基数违规错误

主义\ DBAL \异常\ 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%”]:SQLSTATE [21000]:基数冲突:1241操作数应包含1列。

仅当在WHERE (p.name LIKE (?, ?))的参数列表中定义了多个值时才会出现此错误。我正在使用executeQuery(),并将数组作为Connection::PARAM_STR_ARRAY传递。在原始声明中,我将故障点定义为:

$builder->andWhere('p.name LIKE (:partial_names)'); 

看起来它不像获取作为partial_names传递的数组那样。任何想法是什么导致这种情况,以及如何避免它?

+0

参见HTTP:// stacko verflow.com/questions/1127088/mysql-like-in – bishop

+0

是什么让你认为mysql LIKE可以接受多个参数? –

+0

@YourCommonSense由于'foo LIKE('bar')'在MySQL中有效,我认为'foo LIKE('bar','baz')'也是有效的。 – bishop

MySQL LIKE是一个“字符串比较函数”,并使用“简单模式匹配”将一个字符串与另一个字符串进行比较。

如果您检查SQL standard,您会注意到BNF grammar for 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标准的原因)。 This Q&A显示该行为的一些解决方法,REGEXP基于被接受的答案。

因此,要解决此错误,您需要重写查询以使用多个LIKEREGEXP,或者甚至可以使用像FIND_IN_SET之类的东西。

变化

(p.name LIKE (?, ?)) 

(p.name LIKE ? OR p.name LIKE ?) 

["%big%", "%light%"] 

"%big%", "%light%"