`?` заполнитель для условия SQL `IN` с постоянным`rawSql`

Я был бы счастлив использовать ? заполнитель для заполнения идентификаторов для SQL IN пункт. К сожалению это следующее не работает

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 Похоже, это ужасное название, понятия не имею, как его улучшить

2 ответа

Я не думаю, что есть способ сделать это с persistent,postrgresql-simple (при условии, что мы говорим о Postgres здесь), который используется persistent имеет специальную конструкцию In, которая корректно переводится в In (..) в SQL, но persistent кажется, не использует это. Можно надеяться, что обходной путь - использовать конструктор PersistDbSpecific, который принимает ByteString в качестве аргумента (чтобы мы могли вручную визуализировать и передавать что-то вроде (123,456,789)) но, к сожалению, он преобразуется в SQL через Unknown, который затем обрабатывается через Escape, который не только экранирует строку, но и заключает ее в кавычки, что делает наш SQL недействительным. Если persistent использовали Plain (что, на мой взгляд, имело бы гораздо больше смысла), этот подход будет работать, но, к сожалению, это не так.

Решение - не использовать 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) раздел).

Другие вопросы по тегам