Eri*_*erg 10 sql postgresql jdbc clojure
我找不到用Clojure插入Postgres的数组类型的方法.
(sql/insert! db :things {:animals ["cow" "pig"]})
Run Code Online (Sandbox Code Playgroud)
没有按照我的预期工作.错误信息:
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)
Run Code Online (Sandbox Code Playgroud)
即使是我能找到的最直接的SQL访问也行不通:
(sql/execute! db "INSERT INTO things (animals) VALUES ('{\"cow\", \"pig\"}')")
Run Code Online (Sandbox Code Playgroud)
真的不知道这里发生了什么:
ClassCastException java.lang.Character cannot be cast to java.lang.String clojure.java.jdbc/prepare-statement (jdbc.clj:419)
Run Code Online (Sandbox Code Playgroud)
当然一定有可能吗?如果没有辅助函数,那么通过某种方式执行原始SQL.
jkj*_*jkj 18
您可以通过扩展两个协议使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))))
Run Code Online (Sandbox Code Playgroud)
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"]})
Run Code Online (Sandbox Code Playgroud)
我目前正在开发一个自动支持PostgreSQL和PostGIS类型的库.尽管https://github.com/remodoy/clj-postgresql,它仍然在进行中
使用插入!要插入字符串向量,您必须创建一个实现java.sql.Array的对象(来自字符串向量).您可以使用java.sql.Connection.createArrayOf来创建此类对象
(def con (sql/get-connection db))
(def val-to-insert
(.createArrayOf con "varchar" (into-array String ["cow", "pig"]))
(sql/insert! db :things {:animals val-to-insert})
Run Code Online (Sandbox Code Playgroud)
和
(execute! db-spec [sql & params] :multi? false :transaction? true)
(execute! db-spec [sql & param-groups] :multi? true :transaction? true)
Run Code Online (Sandbox Code Playgroud)
您必须将sql字符串放在向量中才能使其正常工作.
(sql/execute! db ["INSERT INTO things (animals) VALUES ('{\"cow\", \"pig\"}')"])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4009 次 |
| 最近记录: |