我可以遇到类似这样的情况:
SELECT * FROM table WHERE ? LIKE (column || '%')
?
是字符串参数值。例如,当列等于?
/admin/products
应返回true
/admin/products/1
/admin/products/new
/admin/products/1/edit
这可能吗?
更新:添加了测试用例。
基本上,where子句会像这样呈现:
1. ? LIKE (column || '%')
2. '/admin/products/1' like ('/admin/products' || %)
3. '/admin/products/1' like ('/admin/products%')
但它总是对我不利。
但这些查询工作正常:
column = '/admin/products' --returns true
column = '/admin/products/1' --returns false
column LIKE '/admin/prod%' --returns true
当我将参数?
放在LIKE
子句之前时会出现问题。是不允许的?
如果不是,那有什么变通方法吗?
答案 0 :(得分:2)
查询:
SELECT * FROM table WHERE ? LIKE (col || '%');
可以改写为(Postgres和MySQL):
SELECT * FROM table WHERE col = left(?, length(col));
如评论所述,第一种形式也应该有效。但是,这可能很棘手,因为3>列中LIKE
(至少_%\
)的具有特殊含义的字符必须进行转义。如果您希望它与MySQL和Postgres一起使用,那么您必须在两个实现中观察特殊字符。所以第二种形式是在主体上更不容易出错。
这两个查询都不能使用col
上的索引,两者都不是sargable。可以将问题重新评估为找到给定搜索模式?
的所有可能前缀,这些前缀可以像dba.SE上的相关答案(对于Postgres)类似的方式进行优化:
答案 1 :(得分:1)
更换
SELECT * FROM table WHERE ? LIKE (column || '%')
通过
SELECT * FROM table WHERE ? LIKE CONCAT(column, '%')
适合我。
也许||用作逻辑或操作而不是连接。
答案 2 :(得分:0)
适合我。
PREPARE withparam(text) AS SELECT $1 LIKE ('/admin/products' || '%');
EXECUTE withparam('/admin/products/1');
返回true。
您的测试用例似乎无法准确反映当前的实际问题。