我很乐意使用?
占位符来填充SQL IN
子句的ID。不幸的是,它不能正常工作
let idList :: [ RequestId ]
idList = []
let sql :: String
sql = "SELECT ?? FROM request WHERE request.id IN ?"
rs <- runDB $ rawSql sql [ toPersistValue idList ]
这样的代码导致数据库错误,类似于:
syntax error at or near "'[283,282,281]'"
用括号(例如?
)包裹IN (?)
占位符会产生另一种错误:
invalid input syntax for integer: "[283,282,281]"
有没有办法做到这一点?
P.S。看来这标题太可怕了,不知道该如何改进
答案 0 :(得分:1)
我认为persistent
没有办法。
postrgresql-simple
使用的persistent
(假设我们在这里谈论的是Postgres)确实具有特殊的In构造,该构造可以在SQL中正确转换为In (..),但是{{1 }}似乎没有使用它。
可能希望一种解决方法是使用PersistDbSpecific构造函数,该构造函数以persistent
作为参数(以便我们可以手动呈现并传递类似ByteString
的东西),但不幸的是,它通过{然后通过Unknown呈现的{3}}不仅使字符串转义,而且使Escape无效,这使我们的SQL无效。如果(123,456,789)
使用的是encloses it into quotes(我认为这样会更有意义),则此方法有效,但不幸的是,并非如此。
答案 1 :(得分:1)
解决办法是不使用IN
,而是使用更灵活的ANY
函数:
let idList :: [ RequestId ]
idList = []
let sql :: String
sql = "SELECT ?? FROM request WHERE request.id = ANY(?)"
rs <- runDB $ rawSql sql [ PersistArray (map toPersistValue idList) ]
(PersistArray
确保使用数组字面量持久化呈现列表。单独使用 toPersistValue
会出现语法错误)。
您可以在 https://www.postgresql.org/docs/13/functions-comparisons.html 处阅读有关语法的更多信息(查看 ANY/SOME (array)
部分)。