Выражение (параметризованный) ЛЮБОГО (массива) запроса для Postgres в SQLKorma
В настоящее время я использую SQLKorma для проекта, и я сталкиваюсь с небольшим затруднением с ним.
Я построил запрос с двумя левыми соединениями; один из них содержит массив с записями, которые я хочу использовать в моем WHERE
пункт.
Это тривиально, чтобы выразить в SQL. Обратите внимание, что это в основном отредактированный запрос.
SELECT
cu.name,
c.description,
c.created_at AT TIME ZONE 'utc'
FROM calendar_users cu LEFT JOIN calendars c ON cu.id = c.user_id
LEFT JOIN meetings m ON c.id = m.id
WHERE 'status_report' ILIKE ANY (m.meeting_metadata)
GROUP BY m.meeting_metadata, c.created_at, cu.name, cu.description
ORDER BY c.created_at DESC
Доля в отношении ILIKE ANY
это то, что я бы хотел перевести на Корму.
Я понимаю из документов, что ANY
пункт не поддерживается с WHERE
пункт, и я должен изучить использование raw
или же exec-raw
вместо.
С этим я хочу передать в параметризованный raw
строка в WHERE
пункт, чтобы выполнить то, что я пытаюсь пойти.
Это я пытался, но это не с синтаксической ошибкой в Postgres:
(select calendars
(fields calendar-user-cols)
(join :calendar_users (= :calendars.user_id :calendar_users.id))
(join :meetings (= :calendars.id :meetings.id))
(where (raw ["? ILIKE ANY(meetings.meeting_metadata)" metadata])))
В частности:
PSQLException:
Message: ERROR: syntax error at or near "["
Position: 1006
SQLState: 42601
Error Code: 0
Как бы я пошел по этому поводу, используя Korma? Нужно ли прибегать к полномасштабному exec-raw
запрос?
1 ответ
Корма имеет очень полезную функцию korma.core/sql-only
который будет отображать строку SQL, которая будет выполнена.
(defentity calendars)
=> #'korma-test.core/calendars
(sql-only
(select calendars
(fields :x :y)
(join :calendar_users (= :calendars.user_id :calendar_users.id))
(join :meetings (= :calendars.id :meetings.id))
(where (raw ["? ILIKE ANY(meetings.meeting_metadata)" "status_report"]))))
=> "SELECT \"calendars\".\"x\", \"calendars\".\"y\" FROM (\"calendars\" LEFT JOIN \"calendar_users\" ON \"calendars\".\"user_id\" = \"calendar_users\".\"id\") LEFT JOIN \"meetings\" ON \"calendars\".\"id\" = \"meetings\".\"id\" WHERE [\"? ILIKE ANY(meetings.meeting_metadata)\" \"status_report\"]"
или более читаемый:
SELECT "calendars"."x",
"calendars"."y"
FROM ("calendars"
LEFT JOIN "calendar_users" ON "calendars"."user_id" = "calendar_users"."id")
LEFT JOIN "meetings" ON "calendars"."id" = "meetings"."id"
WHERE ["? ILIKE ANY(meetings.meeting_metadata)" "status_report"]
как видите, ILIKE окружен []
, Корма-х raw
просто принимает необработанную строку и не поддерживает параметризацию, такую как exec-raw
делает. Вектор вокруг строки ILIKE был просто превращен в строку с ее содержимым. Вот почему вы получили сообщение Postgres об [
,
Вы должны удалить []
из строки ILIKE, если вы хотите продолжать использовать raw
или посмотреть, если exec-raw
будет соответствовать вашим потребностям лучше. Существует очень реальная опасность внедрения SQL-кода, если вы используете "сырье", хотя вам нужно будет обойтись.
;; require clojure.string :as str in your ns
;; change your clause from
(where (raw ["? ILIKE ANY(meetings.meeting_metadata)" "status_report"])))
;; to this
(where (raw (str/join " " ["'status_report'" "ILIKE ANY(meetings.meeting_metadata)"])))