【问题标题】:Error Thrown While Processing DB Query Resultset处理数据库查询结果集时抛出错误
【发布时间】:2011-07-14 19:36:04
【问题描述】:

谁能帮我理解为什么我的代码(见下文)会导致以下错误:

线程“主”java.lang.UnsupportedOperationException 中的异常: 此类型不支持第 n 个:PersistentStructMap

(defn search [query]
  (with-connection db 
    (with-query-results rs [query] 
      (doseq [[k v] rs] 
        (println v)))))

(search (nth *command-line-args* 0))

【问题讨论】:

    标签: clojure


    【解决方案1】:

    rs 是一个序列(列表),代表结果集中的所有记录。 rs 的每个元素都是一个表示单个记录的哈希映射,映射中的键/值对表示该记录的字段名称和值。您正在尝试执行与此等效的操作:

    user> (let [rs [{:id 1 :val "foo"} {:id 2 :val "bar"}]]
            (doseq [[k v] rs]
              (println v)))
    ; Evaluation aborted.
    ; nth not supported on this type: PersistentArrayMap
    

    这是试图将每个地图解构为[k v],大致相当于:

    user> (let [k (nth {:id 1 :val "foo"} 0)
                v (nth {:id 1 :val "foo"} 1)])
    ; Evaluation aborted.
    ; nth not supported on this type: PersistentArrayMap
    

    如果您尝试打印每条记录中每个字段的值,您需要这样做:

    user> (let [rs [{:id 1 :val "foo"} {:id 2 :val "bar"}]]
            (doseq [record rs
                    [k v] record]
              (println v)))
    foo
    1
    bar
    2
    

    “对于结果集中的每条记录,对于该记录中的每个键/值,打印值。”

    如果您的结果集仅包含一条记录(或者您只关心其中一条记录)并且您尝试遍历该单条记录的字段,则仅传递 doseq first

    user> (let [rs [{:id 1 :val "foo"}]]
            (doseq [[k v] (first rs)]
              (println v)))
    foo
    1
    

    “对于结果集中第一条记录中的每个键/值,打印值。”

    【讨论】:

    • 感谢您的深思熟虑和清晰的解释;这很有帮助。我错误地认为rs 是“包含两项向量的列表,其中一个用于映射中的每个键/值对”(See "How to Iterate Over Map Keys and Values)" 而不是一系列哈希图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-12
    • 2020-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多