2

我目前正在将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是我希望能够翻译成 Korma 的部分。

我从文档中了解到该ANY子句不支持该WHERE子句,我应该考虑使用raworexec-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查询吗?

4

1 回答 1

1

Korma 有一个非常有用的函数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 被[]. Kormaraw只接受一个原始字符串,不支持参数化exec-raw。ILIKE 字符串周围的向量刚刚变成了带有其内容的字符串。这就是您收到有关[.

[]如果您想继续使用,您需要从 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)"])))
于 2015-05-04T23:43:10.483 回答