如何从Clojure中的文本文件动态编写MySQL查询
如何从一列ID的输入文本文件中读取并生成以下格式的MySQL查询:如何从Clojure中的文本文件动态编写MySQL查询,mysql,clojure,Mysql,Clojure,如何从一列ID的输入文本文件中读取并生成以下格式的MySQL查询: SELECT col1,col2,col3 FROM Orders WHERE Id IN ('inputId1','inputId3','inputId3'); 输入文件中的ID以/n分隔,应转换为MySQL查询中用引号括起来的逗号分隔的ID列表 (ns export.core (:require [clojure.java.jdbc :as j]) (:gen-class)) (defn -main [&
SELECT col1,col2,col3 FROM Orders WHERE Id IN ('inputId1','inputId3','inputId3');
输入文件中的ID以/n分隔,应转换为MySQL查询中用引号括起来的逗号分隔的ID列表
(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)))
如果我正确理解了您的问题,我将使用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');"
我猜order 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"))
将list exec raw替换为用于进行SQL调用的任何函数不幸的是,id1恰好是';删除表格命令;-。在?、?中输出Id更安全?然后将实际的ID列表作为参数传递给查询。如果您是从文件中获取列名,那么就没什么可做的了:-/假设这个问题是关于形成字符串的-在答案中添加了这一点,因为最终所有内容都会被剪切并粘贴到somones代码中。我认为假设列名正在生成,并且也与ID相对应是很奇怪的。我只使用col1..col3作为固定列名;这就成为了一个非常常见问题的正确答案。谢谢你的回答。让我澄清几件事。列名将只是我想要拉的任何列。col1、col2等只是示例的占位符,永远不会更改。ID是来自不同电子商务市场的订单ID,因此它们的长度不同,不会增加,而是随机的