clojure.java.jdbc 更新 id 在哪里

Posted

技术标签:

【中文标题】clojure.java.jdbc 更新 id 在哪里【英文标题】:clojure.java.jdbc update where id in 【发布时间】:2016-04-28 20:27:30 【问题描述】:

我正在尝试使用 clojure.java.jdbc 在 Oracle DB 上执行一个简单的更新语句。

(sql/db-do-prepared db "update table_name set active = 1 where id in (?)" ["one" "two"])

但我得到了:

java.sql.SQLException: Invalid column index

我确信所有数据类型都是正确的。看起来 clojure.java.jdbc 不允许这种结构。非常感谢任何反馈

【问题讨论】:

【参考方案1】:

您需要in (?, ?) ...也就是说,您需要与要查找的内容相同数量的问号....(str/join ", " (repeat n "?")) 并且您需要参数不是向量:

(sql/execute! db
  ["update table_name set active = 1 where id in (?, ?)"
   "one" "two"])

请注意,您可以将 sql 和参数放在一个向量中

【讨论】:

在提问之前我试过了 :) 我得到了:ava.sql.SQLException: SQL statement to execute cannot be empty or null 这是正确答案。您可能会再次发布代码以处理您看到的特定异常。此外,还有许多库可以帮助您解决此类问题:HugSQL、Honey SQL【参考方案2】:

由于某些原因,对于大多数数据库来说,准备好的语句很难做到这一点:存在安全隐患,并且不同数据库的语法在这一点上有所不同。

我不完全确定这对于 clojure jdbc 包是否可行。 对于 Oracle,您可以尝试回退到 oracle java jdbc 包,创建一个 ARRAY 类型实例并将其作为单个参数传递。 Official doc

就像@Timothy Pratley 写的那样,最常见的解决方案是添加尽可能多的占位符。 已经讨论了其他一些替代方案here

【讨论】:

【参考方案3】:

在想要运行在where 条件中具有in 子句的SQL 的一般情况下,您需要这样的东西:

(sql/query db-spec (into [(str "SELECT ... WHERE col IN ("
                               (str/join "," (repeat (count values) "?"))
                               ")")]
                         values))

字符串连接有时很难看。正如 Curtis Summers 在对 Timothy Pratley's answer 的评论中指出的那样,使用 HoneySQL 之类的东西可以让这不那么令人不快。

【讨论】:

【参考方案4】:

正如柯蒂斯所说,使用 HoneySQL+clojure.java.jdbc 实现这一点:

(require '[clojure.java.jdbc :as j])

(def example-q
  (-> (select :*)
      (from [:table :t])
      (where [:in :param :?param])))

(sql/format example-q :params :param ["a" "b" "c"])
=> ["SELECT * FROM table AS t WHERE param IN (?, ?, ?)" "a" "b" "c"]
;; then running:
(j/query db (sql/format example-q :params :param ["a" "b" "c"]))

对于 next.jdbc,我会使用 execute-batch:

(require '[next.jdbc :as jdbc])

(def update-q
  "UPDATE t
   SET col=0
   WHERE id
   IN (?)")

(jdbc/execute-batch! ds update-q [["1"] ["2"]] )

【讨论】:

以上是关于clojure.java.jdbc 更新 id 在哪里的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 clojure.java.jdbc 进行 UPSERT

java.jdbc clojure 执行!插入数量

使用clojure.java.jdbc在Clojure中使用外键约束

如何使用 clojure.java.jdbc 插入包含时间戳值的行?

clojure.java.jdbc /查询大结果集懒惰

clojure/java.jdbc 和 postgres:Prepared statments 比字符串连接查询慢 100 倍?