如何在clojure.contrib.sql中调用resultset上的next()?

时间:2010-11-16 09:08:56

标签: sql clojure next seq

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

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

编辑#2这是一段代码:

(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。我想知道是否有更清洁,惯用的方法来做到这一点?

2 个答案:

答案 0 :(得分:3)

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

通常你根本不打电话。要成为惯用语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

答案 1 :(得分:1)

怎么样

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

如果返回一行,则返回某些内容;如果没有匹配的行,则返回nil

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

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

Connection