我已将表单提交到同一页面,我可以显示提交的值,但是当我尝试插入提交/发布的值时,我正在努力学习语法。如何将值作为变量访问?编写此行的正确方法是什么?我在哪里引入插入查询?
(query-exec sql-exp "insert into students(name) values ( '`post-body a-post')")
我可以使用以下代码显示值:
; render-post: post -> xexpr ; Consumes a post, produces an xexpr fragment of the post. (define (render-post a-post) `(div ((class "post")) "Title : " ,(post-title a-post) (p ,"Post : " ,(post-body a-post)))) ; render-posts: blog -> xexpr ; Consumes a blog, produces an xexpr fragment ; of all its posts. (define (render-posts a-blog) `(div ((class "posts")) ,@(map render-post a-blog)))
答案 0 :(得分:0)
documentation for query-exec中的第二个示例显示了如何执行接收参数的数据库查询。
例如,假设我们有一个food
表,其中包含name
和calories
列,我们可以编写一个可以插入该表的函数。
;; insert-food!: database-connection string number -> void
;; Inserts an element into the food table.
(define (insert-food! conn name cals)
(query-exec conn
"insert into food (name, calories) values ($1, $2)"
name
cals))
我们正在使用parameterized query,假设数据库是PostgreSQL或支持使用占位符$1
,$2
等的数据库,并将这些占位符的值作为附加值传递query-exec
的参数。
如果您正在从外部世界获取输入并使用它构建SQL查询,那么应该知道如何使用参数化查询,否则您将面临数据库安全的风险。 不尝试格式化单个字符串,将所有变量的值插入到一个查询字符串中:您可能会错误地将其打开并将程序打开到SQL injection漏洞。相反,将这些值作为不同的参数传递给query-exec
。
另请注意,上述功能不需要在Web服务器的上下文中使用:例如,它可以在unit testing的上下文中使用。您可能想要来测试此函数,而无需在Web servlet中使用它。像这样:
#lang racket
(require db)
;; We want to export the following functions to outside clients.
(provide [struct-out foo]
insert-food!
get-foods!)
;; A food is a:
(struct food (name ;; string
cals) ;; number
#:transparent)
;; insert-food!: database-connection food -> void
;; Inserts an element into the food table.
(define (insert-food! conn a-food)
(query-exec conn
"insert into food (name, calories) values ($1, $2)"
(food-name a-food)
(food-cals a-food)))
;; get-foods!: database-connection -> (listof food)
;; Get a list of the foods in the database.
(define (get-foods! conn)
(for/list ([(name cal)
(in-query conn "select name, calories from food")])
(food name cal)))
(module+ test
(require rackunit)
;; Internal test. We'll use an in-memory SQLite database.
(define conn (sqlite3-connect #:database 'memory))
(query-exec conn "create table food (name string, calories double)")
;; Initially, it should be empty.
(check-equal? (get-foods! conn) '())
;; Now let's add a food:
;; http://www.eiyoukeisan.com/JapaneseFoodCalorie/zryouri/misoramen.html
(insert-food! conn (food "miso ramen" 56000.0))
;; Can we get it back?
(check-equal? (get-foods! conn) (list (food "miso ramen" 56000.0))))
现在,您可以通过在DrRacket中运行此文件来测试这些数据库函数的功能。一旦我们知道它们可靠地工作,那么我们就可以在不同的上下文中使用它们,例如web servlet。
尝试在与HTTP请求处理程序相同的位置执行此操作可能是错误的方法。您希望数据模型(数据库操作)与HTTP请求处理程序位于一个单独的模块中,否则可能会使数据模型难以测试。这就是Continue web-server tutorial不遗余力地将“模型”作为一个单独的模块提取的主要原因。