2

我很乐意使用?占位符来填充 SQLIN子句的 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]"

有没有办法做到这一点?

PS 貌似是个烂标题,不知道怎么改

4

2 回答 2

1

我不认为有办法做到这一点persistentpostrgresql-simple(假设我们在这里讨论的是 Postgres)persistent确实有特殊的In构造,它在 SQL中被正确翻译成In (..)persistent ,但似乎没有使用它。人们可能希望一种解决方法是使用作为参数的PersistDbSpecific构造ByteString函数(因此我们可以手动渲染和传递类似的东西(123,456,789)),但不幸的是,它通过Unknown转换为 SQL ,然后通过Escape渲染,这不仅转义了字符串,而且将其括在引号中,这使我们的 SQL 无效。如果persistent使用普通(在我看来这会更有意义)这种方法会起作用,但不幸的是事实并非如此。

于 2019-01-17T08:21:10.963 回答
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)部分)。

于 2021-06-03T18:16:35.210 回答