Clojure read Oracle Blob



我需要在 Clojure 中将几何图形读取为 WKB 字符串,为此我尝试使用 clojure/java.jdbc

(require '[clojure.java.jdbc :as j])    
(->> (j/query db "select SDO_UTIL.TO_WKBGEOMETRY(geometry) wkb from t where idf = 1") 
  (map #(-> % :wkb .getBinaryStream .readAllBytes)))

不幸的是,我得到了:

Exception thrown: java.sql.SQLRecoverableException (Closed Connection)
getDBAccess - (BLOB.java:1122)
getBinaryStream - (BLOB.java:265)
invoke0 - (NativeMethodAccessorImpl.java:-2)
invoke - (NativeMethodAccessorImpl.java:62)
invoke - (DelegatingMethodAccessorImpl.java:43)
invoke - (Method.java:498)
invokeMatchingMethod - (Reflector.java:93)
invokeNoArgInstanceMember - (Reflector.java:313)
eval16213/fn - user - (form-init2938139155321903837.clj:3)
map/fn - clojure.core - (core.clj:2646)

所以我可以使用oracle.sql.Blob/length读取blob中的字节数

(->> (j/query db "select SDO_UTIL.TO_WKBGEOMETRY(geometry) wkb t where idf = 1") 
(map #(-> % :wkb .length))
)
(42241)

看起来像我所说的"懒惰的错误"。

连接被打开并发送查询,然后它返回一个序列,其中包含一些代码,当程序的下一部分从序列中读取时,该序列将从数据库获取响应。 在这种情况下,数据库连接在发生这种情况之前关闭。

幸运的是,它很容易修复,只需在地图上放一个doall

(require '[clojure.java.jdbc :as j])    
(->> (j/query db 
              "select SDO_UTIL.TO_WKBGEOMETRY(geometry)
               wkb t where idf = 1") 
  (map #(-> % :wkb .getBinaryStream .readAllBytes))
  doall)

这段代码对我有用,由 @Arthur doall 建议对我的情况没有帮助,我添加的是一个事务:

(require '[clojure.java.jdbc :as j])
(j/with-db-transaction [t-con db ] 
 (->> (j/query t-con  
          "select SDO_UTIL.TO_WKBGEOMETRY(geometry)
           wkb from  t where idf = 1  ")                                          
    (map #(-> % :wkb .getBinaryStream))
    (map #(java.util.Scanner. %))
    (map #(.next %))
    doall
   )
)

最新更新