Clojure阅读Oracle Blob

时间:2018-04-18 12:02:59

标签: clojure ojdbc clojure-contrib

我需要在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)

2 个答案:

答案 0 :(得分:0)

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

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

幸运的是,它很容易修复,只需在地图上放置一个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)

答案 1 :(得分:0)

这段代码对我有用,@ 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
   )
)