【问题标题】:clojure.java.jdbc update where id inclojure.java.jdbc 更新 id 在哪里
【发布时间】: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 不允许这种结构。非常感谢任何反馈

【问题讨论】:

    标签: oracle jdbc clojure sql-update


    【解决方案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
    • 这是正确答案。您可能会再次发布代码以处理您看到的特定异常。此外,还有许多库可以帮助您解决此类问题:HugSQLHoney 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"]] {})
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-12
          • 1970-01-01
          • 2012-12-01
          • 2015-06-16
          • 1970-01-01
          • 2017-12-04
          • 1970-01-01
          • 2017-05-20
          相关资源
          最近更新 更多