球拍/方案:如何使用可变数量的参数构造查询?

时间:2014-01-20 16:51:59

标签: scheme racket

我坚持这个问题,搜索一个干净的方式来构建这个查询。

基本上,我愿意在表的某些字段上运行更新,但确切的字段将是动态的,并由传递给函数的参数决定。

(define
  (update-user user-id
               #:first-name [first-name #f]
               #:last-name [last-name #f])
    (query-exec
     dbc
     (string-append
      "UPDATE user"
      (if first-name
      "SET first_name = ?"
      ""
      )
      (if last-name
      "SET last_name = ?"
      ""
      )
      "WHERE identifier = ?")

     ; ?? how to pass dynamically the arguments ?

      user-id
     ))

因此,仅当提供参数时,更新才应在first_name上运行,与姓氏相同。我可以自己构建查询,但是之后我不知道如何传递(或不传递!)参数。

或者查询应该以完全不同的方式构建?

提前致谢!

1 个答案:

答案 0 :(得分:2)

免责声明:我之前只使用了query-exec 的模拟版本,因此您可能需要进行一些细微的更改:

您可以使用applylist*混合执行此操作:

(define (build-query con pre verb post lst)
  (let ((key (car lst)))
    (let loop ((lst (cdr lst)) (sql "") (parms '()))
      (if (or (null? lst) (null? (cdr lst)))
          (list* con (string-append pre " " sql " "  post) (reverse (cons key parms)))
          (let ((field (car lst)) (val (cadr lst)))
            (loop 
             (cddr lst) 
             (string-append sql (format "~a ~a=?" (if (null? parms) verb ",") field))
             (cons val parms)))))))

然后

(apply query-exec (build-query con "UPDATE user" "SET" "WHERE identifier=?" '("123456" "first_name" "Patrick")))
=> (query-exec con "UPDATE user SET first_name=? WHERE identifier=?" "Patrick" "123456")

(apply query-exec (build-query con "UPDATE user" "SET" "WHERE identifier=?" '("123456" "first_name" "Patrick" "last-name" "Useldinger")))
=> (query-exec con "UPDATE user SET first_name=?, last-name=? WHERE identifier=?" "Patrick" "Useldinger" "123456")