我想使用一个函数或宏来创建一个 SQL 语句,方法是使用一个包含键值形式的参数的列表。
例如:(("id"3) ("version"3) ("name""foo") ("age"10))
我想返回一个像
这样的字符串“插入表('id','版本','名称','年龄')值(3,3,'foo',10);”
这是我的代码:
(defvar *param* '(("id" 3) ("version" 3) ("name" "foo") ("age" 10)))
(defun dis (elt)
(if (stringp elt)
(concatenate 'string "'" elt "'")
(write-to-string elt)))
(defun tostring (lst)
(if (eql 1 (length lst))
(dis (car lst))
(concatenate 'string (dis (car lst)) "," (tostring (cdr lst)))))
(defun fillinsert (lst)
(let ((keys (mapcar #'car lst))
(values (mapcar #'cadr lst)))
(concatenate 'string
"insert into table ("
(tostring keys)
") values("
(tostring values)
");")))
我不知道如何仅访问该列表一次来创建字符串。 谢谢
最佳答案
没有使用FORMAT
我写了下面的代码。主要思想是使用常用的输出函数来创建所需的内容。然后,WITHOUT-OUTPUT-TO-STRING
形式将此输出作为字符串返回 - 无论输出和字符串有多长。这样您就不必一直创建字符串并连接字符串,这既丑陋又通常效率低下。
(defun create-sql-sentence (kvl)
(flet ((format-list (list key)
(write-string "(")
(loop for start = t then nil
for kv in list
for item = (funcall key kv)
unless start do (write-string ",")
do (typecase item
(string
(write-string "'")
(write-string item)
(write-string "'"))
(t
(write item))))
(write-string ")")))
(with-output-to-string (*standard-output*)
(write-string "insert into table ")
(format-list kvl #'first)
(write-string " values")
(format-list kvl #'second)
(write-string ";"))))
上面没有使用递归。
它也不会重复使用连接
。
它也不会重复调用 length
。
关于common-lisp - 如何在 Common Lisp 中使用 SQL 参数列表循环来创建 SQL 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17808563/