【问题标题】:How to call next() on a resultset in clojure.contrib.sql?如何在 clojure.contrib.sql 的结果集上调用 next()?
【发布时间】:2010-11-16 09:08:55
【问题描述】:

最初我想问为什么我在结果集上调用 (seq) 作为空性测试时遇到问题,但一些研究表明这显然是因为 jdbc 光标没有移动到任何地方。很好,花花公子。如果我不知道它的名字,有没有办法在结果集上调用 next() ?我可以将它绑定到 clojure 中的符号,但我无法弄清楚如何从那里调用该方法。

编辑:如果不清楚,我指的是java resultSet方法next(),而不是clojure(next)

edit#2 这是一个代码 sn-p:

(defn user-exists? [email]
  (with-connection db
   (with-query-results res ["SELECT guid from users WHERE email=?" email]
    (.next res)
    (seq res))))

(感谢.next 的帮助,顺便说一句...还没有做太多的 java 互操作)

不过,如果查询没有返回任何内容,使用 (seq) 会引发 NullPointerException。我想知道是否有更清洁、惯用的方法来做到这一点?

【问题讨论】:

  • 能否贴出相关代码sn-p?也许你错过了一些简单的东西。此外,如果您将 ResultSet 绑定到某个东西,(.next resultset) 将是您在其上调用 next() 的方式。

标签: sql clojure next seq


【解决方案1】:

res 将绑定到基于 ResultSet 的 Clojure 序列,其中每个项目是结果记录的映射,其中输出列名称作为键中的关键字。您无法访问底层的实际 ResultSet 对象。

通常您根本不会调用 next。要成为惯用的 Clojure,您将利用对序列(map、filter、reduce 等)进行操作的庞大函数库来生成输出。在这里你可能会这样说:

(with-query-results res ["SELECT guid from users WHERE email=?" email]
  (map :guid res))

这会将 :guid 作为函数应用于 res seqeuence 并检索每条记录中 guid 的列值,为您返回所有 guid 的新序列。然后,您可以将该地图包装在过滤器或您需要的任何其他东西中。

在这种情况下,seq 应该是您想要的,但我认为抽象有点泄漏。当我尝试它时,我得到了 java.sql.SQLRecoverableException: Closed Resultset: next 这意味着 ResultSet 在抽象中被关闭得太早了。但是,我发现 empty? 在这个用例中工作正常。

(defn user-exists? [email]
  (with-connection db
   (with-query-results res ["SELECT guid from users WHERE email=?" email]
    (.next res)
    (not (empty? res)))))

对我来说,这似乎是 clojure.core/resultset-seq 中的一个错误,我在这里将其报告为 CLJ-676

【讨论】:

  • 也许问题是来自map 的惰性序列正在with-query-results 范围之外进行评估,因此结果集已关闭。如果map 包裹在doall 中,问题是否仍然存在?
  • (doall res) 在触摸结果之前为我解决了问题。
【解决方案2】:

怎么样

(defn user-exists? [email]
  (with-connection db
    (with-query-results res ["SELECT guid from users WHERE email=?" email]
      (first res))))

如果返回一行,则应该返回 something,如果没有匹配的行,则返回 nil

您之前的查询失败了,因为res 是调用(resultset-seq x) 的值,因此您不能在其上使用Java 的ResultSet.next(),也不想再次调用seq

如上所述,您必须在ResultSet(和Connection)打开时评估resultset-seq,因此您必须拥有

(defn users-with-email [email]
  (with-connection db
    (with-query-results res ["SELECT guid from users WHERE email=?" email]
      (doall res))))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-16
    • 1970-01-01
    • 1970-01-01
    • 2019-07-12
    • 1970-01-01
    • 1970-01-01
    • 2018-01-11
    相关资源
    最近更新 更多