如何在 clojure.contrib.sql 中的结果集上调用 next() ?
最初我想问为什么我在结果集上调用 (seq) 作为空性测试时遇到问题,但一些研究表明,这显然是因为 jdbc 光标没有移动到任何地方。很好,花花公子。如果我不知道结果集的名称,有没有办法在结果集上调用 next() ?我可以将它绑定到 clojure 中的符号,但我无法弄清楚如何从那里调用该方法。
编辑:如果不清楚,我指的是 java resultSet 方法 next(),而不是 clojure (next)
edit#2 这是一个代码片段:(
(defn user-exists? [email]
(with-connection db
(with-query-results res ["SELECT guid from users WHERE email=?" email]
(.next res)
(seq res))))
感谢 .next 的帮助,顺便说一句...haven'不过
,如果查询没有返回任何内容,使用 (seq) 会抛出 NullPointerException。我想知道是否有更干净、惯用的方法来做到这一点?
Originally I was going to ask why I was having problems calling (seq) on a result set as a test for emptiness, but a bit of research showed that it's apparently because the jdbc cursor hasn't moved anywhere. Fine and dandy. Is there a way to call next() on the resultset if I don't know its name? I can bind it to a symbol in clojure, but I haven't been able to figure out how to call the method from there.
edit: in case it's not clear, I'm referring to the java resultSet method next(), not the clojure (next)
edit#2 here's a code snippet:
(defn user-exists? [email]
(with-connection db
(with-query-results res ["SELECT guid from users WHERE email=?" email]
(.next res)
(seq res))))
(Thanks for the help on .next, btw...haven't done much java interop yet)
Still, though, using (seq) throws a NullPointerException if the query didn't return anything. I'm wondering if there's a cleaner, idiomatic way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
res 将绑定到基于 ResultSet 的 Clojure 序列,其中每个项目都是结果记录的映射,其中输出列名称作为键中的关键字。您无法获取底层的实际 ResultSet 对象。
通常你根本不会再打电话。按照 Clojure 的习惯,您将利用对序列进行操作的庞大函数库(映射、过滤、归约等)来生成输出。在这里,您可能会说:
这会将 :guid 作为函数应用于 res 序列,并检索每个记录中 guid 的列值,返回所有 guid 的新序列。然后,您可以将该地图包装在过滤器或任何您需要的其他内容中。
在这种情况下, seq 应该是您想要的,但我认为抽象有点泄漏。当我尝试时,我得到了 java.sql.SQLRecoverableException: Closed Resultset: next 这对我来说意味着 ResultSet 在抽象中关闭得太早了。但是,我发现
empty?
对于这个用例来说工作正常。对我来说,这似乎是 clojure.core/resultset-seq 中的一个错误,我在这里将其报告为 CLJ-676。
res will be bound to a Clojure sequence based on the ResultSet where each item is a map of a result record with output column names as keywords in keys. You can't get to the underlying actual ResultSet object.
Typically you don't call next at all. To be idiomatic Clojure, you would utilize the vast library of functions that operate on sequences (map, filter, reduce, etc) to produce your output. Here you might say something like:
which would apply :guid as a function over the res seqeuence and retrieve the column value of guid in each record, returning you a new sequence of all the guids. You could then wrap that map in a filter or whatever else you needed.
In this case,
seq
should be what you want but I think the abstraction is leaking a bit. When I tried it I got java.sql.SQLRecoverableException: Closed Resultset: next which implies to me the ResultSet is being closed too early in the abstraction. However, I foundempty?
worked ok for this use case.This seems like a bug in clojure.core/resultset-seq to me and I reported it here as CLJ-676.
。
如果返回一行,则应该返回something,如果没有匹配的行,则应该返回
nil
您之前的查询失败,因为
res
是调用(resultset-seq x)
的值,因此您无法使用 Java 的ResultSet.next()
,您也不想再次对其调用seq
。如前所述,您必须在
ResultSet
(和Connection
)打开时评估resultset-seq
,因此您必须How about
That should return something if a row is returned, or
nil
if there's no matching row.Your earlier query was failing because
res
is the value of a call to(resultset-seq x)
, so you can't use Java'sResultSet.next()
on it, nor do you want to callseq
on it again.As noted, you have to evaluate the
resultset-seq
while theResultSet
(andConnection
) is open, so you would have to have