Как позвонить следующему () на результате наборе в clojure.contrib.sql?

StackOverflow https://stackoverflow.com/questions/4192518

  •  10-10-2019
  •  | 
  •  

Вопрос

Первоначально я собирался спросить, почему у меня возникли проблемы, вызывая (SEQ) в результате, установленном в качестве теста на пустоту, но некоторые исследования показали, что это, очевидно, потому что курсор JDBC никуда не двигался. Хорошо и денди. Есть ли способ позвонить по следующему () на результате, если я не знаю его названия? Я могу связать его с символом в Clojure, но я не смог выяснить, как вызвать метод оттуда.

РЕДАКТИРОВАТЬ: В случае, если это не ясно, я имею в виду метод ResultSet Java 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 Interop)

Тем не менее, однако, использование (SEQ) бросает NullPointerException, если запрос ничего не вернул. Мне интересно, есть ли более чистый, идиоматический способ сделать это?

Это было полезно?

Решение

RES будет связан с последовательности Clojure, основанной на результатах, где каждый элемент представляет собой карту записи результата с именами вывода в качестве ключевых слов в клавишах. Вы не можете добраться до базового фактического объекта результатов.

Обычно вы вообще не звоните дальше. Чтобы быть идиоматическим Clojure, вы использовали бы обширную библиотеку функций, которые работают на последовательностях (MAP, фильтр, уменьшение и т. Д.) Для получения вашего вывода. Здесь вы можете сказать что -то вроде:

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

который будет применяться: GID в качестве функции в отношении SEQUENCE и извлечь значение столбца GUID в каждой записи, возвращая вам новую последовательность всех гид. Затем вы можете обернуть эту карту в фильтр или что -то еще, что вам нужно.

В таком случае, seq Должно быть то, что вы хотите, но я думаю, что абстракция немного протекает. Когда я попробовал это, я получил java.sql.sqlrecoverableexception: закрытый результат: Далее что подразумевает мне, что результат набор закрывается слишком рано в абстракции. Однако я нашел 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.

Другие советы

Как насчет

(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() на нем, и вы не хотите позвонить seq на нем снова.

Как отмечалось, вы должны оценить resultset-seq в то время как ResultSet (а также Connection) открыт, так что вам нужно было

(defn users-with-email [email]
  (with-connection db
    (with-query-results res ["SELECT guid from users WHERE email=?" email]
      (doall res))))
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top