:clojure中的result-set-fn jdbc返回错误“结果集已关闭”。为什么呢?

时间:2017-10-23 09:37:08

标签: sql-server database postgresql jdbc clojure

我经常需要从数据库服务器加载大量数据。有时它有数百万行甚至更多。所以我试着懒洋洋地下载数据。那就是我想做的事情:我想得到一个懒惰的序列并从服务器拉取数据部分,即如果行数大于500,我想主要得到那个懒惰序列前500个元素的帮助,然后通过另一个请求我想要接收下一个500个元素,依此类推,直到我收到服务器上的所有数据。

但我有一个问题。 Clojure jdbc实现了整个延迟序列,但我想部分地从中获取数据。 我研究这个问题并找到关于类似问题的好回复: clojure.java.jdbc lazy query

我拿了这个例子写了这个:


(defn get_data
   [arg1 arg2]
   (let [full-db-spec (get ...)
       sql_query (get ...)
       row-n (atom 0)
       prepared-statement (-> full-db-spec
                               (jdbc/get-connection)
                               (jdbc/prepare-statement sql_query {:fetch-size 3}))]
     (jdbc/with-db-transaction [tx full-db-spec]
       (jdbc/query full-db-spec [prepared-statement arg1 arg2]
           {:fetch-size 3
            :row-fn (fn [r] (do (prn "r" @row-n) (swap! row-n inc) r))
            :result-set-fn identity}))))

这里我想得到一个懒惰序列,以便从这个懒惰序列中进一步部分提取数据。但是当:result-set-fn包含identity(take 500 ...)时,代码会返回错误:The result set is closed.为什么?但是当我改变:result-set-fn为first或doall或last时它工作正常,但它实现了完整的懒惰序列!

我用:

  • ms sql [com.microsoft.sqlserver/mssql-jdbc "6.3.3.jre8-preview"](我在postgresql [org.postgresql/postgresql "9.4.1212.jre7"]上测试。结果相同)
  • [org.clojure / java.jdbc“0.7.3”]

1 个答案:

答案 0 :(得分:4)

该延迟序列正在从您的连接读取值,但该连接在with-db-transaction范围之外关闭。您需要在该范围内实现/进行进一步处理。