sql - 使用 Clojure 插入 PostgreSQL 数组

标签 sql postgresql jdbc clojure

我找不到用 Clojure 插入 Postgres 数组类型的方法。

(sql/insert! db :things {:animals ["cow" "pig"]})

没有像我预期的那样工作。错误信息:

PSQLException Can't infer the SQL type to use for an instance of clojure.lang.PersistentVector. Use setObject() with an explicit Types value to specify the type to use.  org.postgresql.jdbc2.AbstractJdbc2Statement.setObject (AbstractJdbc2Statement.java:1936)

即使是我能找到的最直接的 SQL 访问也不起作用:

(sql/execute! db "INSERT INTO things (animals) VALUES ('{\"cow\", \"pig\"}')")

真的不知道这里发生了什么:

ClassCastException java.lang.Character cannot be cast to java.lang.String  clojure.java.jdbc/prepare-statement (jdbc.clj:419)

肯定有可能吗?如果不是通过辅助函数,则通过某种方式执行原始 SQL。

最佳答案

您可以通过扩展两个协议(protocol)使 clojure.java.jdbc 自动在 Clojure 向量和 SQL 数组之间进行转换。这可以通过您自己的代码完成:

(extend-protocol clojure.java.jdbc/ISQLParameter
  clojure.lang.IPersistentVector
  (set-parameter [v ^java.sql.PreparedStatement stmt ^long i]
    (let [conn (.getConnection stmt)
          meta (.getParameterMetaData stmt)
          type-name (.getParameterTypeName meta i)]
      (if-let [elem-type (when (= (first type-name) \_) (apply str (rest type-name)))]
        (.setObject stmt i (.createArrayOf conn elem-type (to-array v)))
        (.setObject stmt i v)))))

(extend-protocol clojure.java.jdbc/IResultSetReadColumn
  java.sql.Array
  (result-set-read-column [val _ _]
    (into [] (.getArray val))))

REPL 示例:

user> (def db (clj-postgresql.core/pool :dbname "test"))
#'user/db
user> (clojure.java.jdbc/query db ["SELECT ?::text[], ?::int[]" ["foo" "bar"] [1 2 3]])
({:int4 [1 2 3], :text ["foo" "bar"]})

我目前正在开发一个将自动支持 PostgreSQL 和 PostGIS 类型的库。虽然仍有很多工作在进行中 https://github.com/remodoy/clj-postgresql

关于sql - 使用 Clojure 插入 PostgreSQL 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22959804/

相关文章:

php - MYSQL : SET value in an UPDATE query when all conditions of subquery are satisfied

java - 你如何在 Spring 中配置数据源?

sql - 如何处理触发器中的错误?

ruby-on-rails - 使用 Rails 5 在 Postgres 中存储字符串化 JSON

postgresql - 如何在 Kubernetes 上实现 Postgres 备份?

postgresql - 使用 Postgres 索引嵌套的 json

java - ResultSet——它是什么样的对象?

java - 防止多个主键错误

php - 按连续小时获取sql

php - 了解准备好的语句 - PHP