【发布时间】:2018-02-01 16:19:34
【问题描述】:
我尝试在我的应用程序中使用可空变量,并将其发送到具有默认空列的数据库。
这是一个示例结构:
// Location type
type Location struct {
ID int `schema:"id"`
Title *string `schema:"title"`
}
Title 定义为 *string,因为它可以为 null(例如,没有用户输入或客户端应用程序将其作为 null 发送)。
这是我接收表单数据的函数:
// JSONLocationCreate func
func (a *App) JSONLocationCreate(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
var e Location
err := decoder.Decode(&e, r.PostForm)
if err != nil {
respondWithError(w, http.StatusBadRequest, "Invalid request payload")
return
}
// --- SUCCESS ---
// If e.Title has data, the following line works.
// --- FAIL ---
// If e.Title doesn’t have data (for whatever reason), it’s null, and crashes the app:
log.Println(*e.Title)
// Ultimately the variable would be sent off to a database.
// Below I’m removing other functions and such, just including my statement line.
// --- SUCCESS ---
// If e.Title has data, the following line works.
// --- FAIL ---
// If e.Title is null (e.g. no user input), this crashes the app.
statement := fmt.Sprintf("INSERT INTO locations(title) VALUES('%s')", *e.Title)
// In either case, the crash error is similar to this:
// panic serving [::1]:52459: runtime error: invalid memory address or nil pointer dereference
}
问题 1:如何在整个应用程序中使用可空变量(如 e.Title),而不会在变量为空时引发恐慌错误?将其包装在将 null 转换为“”字符串的函数中是最佳实践吗?如何透明地应用这样的函数,这样我就不必在变量的每个实例上都有类似“nullCheck(*e.Title)”的东西?
问题 2: 对于我的数据库查询,我不能将“”字符串值发送到数据库中来代替空值。到目前为止,我的查询是手动构建的。我想我需要一个函数来生成 SQL 查询,当变量为空时自动排除列和变量。
我在正确的轨道上吗?有什么例子吗?
经过数小时的搜索,我还没有理解所有的主题/教程。
【问题讨论】:
-
您应该使用
sql.NullX类型。你可以阅读更多关于medium.com/aubergine-solutions/… -
感谢您的文章。我已经实现了它的结构处理程序。在这一点上,一切似乎都很好,除了我在解码我的 postform 时失败了。这篇文章和其他文章似乎主要涉及 db-to-json,而不是相反。
-
好的,因为我使用的是 Gorilla Schema,如果使用那篇文章中的自定义结构处理程序,我还有额外的步骤要做。这是一个关于它的帖子:stackoverflow.com/questions/27744493/…
-
无论如何,在尝试使用我的变量时,我似乎仍然需要做更多的事情。我看到当得到一个空变量时,它被保存在一个数组中。伙计,这是一个很深的兔子洞。我决定恢复使用无空数据库设计,无论我从中得到什么头痛,我都会在未来处理它……就这样吧;不管 NULL 提供什么优势……我现在有更大的鱼要炸。
标签: go