如何在Clojure

时间:2016-06-03 22:40:06

标签: mysql clojure

如何读取1列ids的输入文本文件并生成格式的MySQL查询:

SELECT col1,col2,col3 FROM Orders WHERE Id IN ('inputId1','inputId3','inputId3');

输入文件中的id由/ n分隔,并且应该转换为用MySQL查询的引号括起来的逗号分隔的Ids列表。

(ns export.core
  (:require [clojure.java.jdbc :as j])

  (:gen-class))

(defn -main [& args]

  ;; Get home directory
  (def out-file
    (str (System/getProperty "user.home") "/Desktop/export.txt"))

  (def in-file
    (str (System/getProperty "user.home") "/Desktop/orders.txt"))

  ;; Get string of order-ids
  (def order-ids-string (slurp in-file))

  ???????????
  ???????????

  ;; Connect to database
  (def db {:subprotocol "mysql"
           :subname "XXXXXXXX"
           :user "XXXXXXX"
           :password "XXXXXXX"})

  ;; Get headers
  (def header-seq
    (j/query db ["DESCRIBE Orders"] :row-fn :field))

  (def header-str
    (str (clojure.string/join "\t" header-seq) "\n"))

  ;; Get product results and spit data to file
  (def header-keys
    (into []
       (map keyword
          (map clojure.string/lower-case header-seq))))

  (def data-seq
    (j/query db [<needed sql query>]))

  (defn select-values [map]
    (reduce #(conj %1 (map %2)) [] header-keys))

  (spit out-file header-str)

  (doseq [row data-seq]
    (spit out-file
      (str (clojure.string/join "\t" (select-values row)) "\n")
     :append true)))

1 个答案:

答案 0 :(得分:2)

如果我正确理解了您的问题,我会使用line-seq,string / join和format来形成查询:

首先是一些测试数据:

(spit "/tmp/input-file" "id1\nid2\nid3\nid4\n")

然后让我们回读并形成一个字符串

user> (let [ids (line-seq (clojure.java.io/reader "/tmp/input-file"))
            col-names (clojure.string/join "," (map #(str "col" %) (range 1 (inc (count ids)))))
            col-ids (clojure.string/join "," (map #(str "'"% "'") ids))]
        (format "SELECT %s FROM Orders WHERE Id IN (%s);" col-names col-ids))

"SELECT col1,col2,col3,col4 FROM Orders WHERE Id IN ('id1','id2','id3','id4');"

我猜测订单ID的数量与文件中的行数相匹配,并且他们应该在名称中获得序列号。

正如amalloy所指出的那样,使用查询参数基本上总是更好:

user> (let [ids (line-seq (clojure.java.io/reader "/tmp/input-file"))
            col-names (clojure.string/join "," (map #(str "col" %) (range 1 (inc (count ids)))))            
            question-marks (clojure.string/join "," (repeat (count ids) "?"))]
        (list 'exec-raw (format "SELECT %s FROM Orders WHERE Id IN (%s);" col-names question-marks) ids))
(exec-raw "SELECT col1,col2,col3,col4 FROM Orders WHERE Id IN (?,?,?,?);" ("id1" "id2" "id3" "id4"))

(用您用于进行SQL调用的任何函数替换list exec-raw