Lazyboy果然又lazy了,一周没写东西。
GO DATABASE/SQL Tutorial
Handling Errors
几乎所有对 database/sql类型的操作都会有一个error作为返回值的最后一个值。我们应该每次都要检查错误,不要忽略掉。
有的地方的错误行为比较特殊,我们需要了解一些额外的东西。
Errors From Iterating Resultsets
for rows.Next() {
// ...
}
if err = rows.Err(); err != nil {
// handle the error here
}
rows.err()中的错误可能是rows.next()循环中各种错误的结果。循环可能出于某种原因退出,而不是正常完成循环,因此您总是需要检查循环是否正常终止。异常终止会自动调用rows.close(),尽管多次调用它是无害的。
Errors From Closing Resultsets
如前所述,如果过早退出循环,则应显式关闭sql.rows。如果循环正常退出或发生错误,它将自动关闭,但我们可能会错误地执行此操作:
for rows.Next() {
// ...
break; // rows没有关闭,内存泄漏
}
if err = rows.Close(); err != nil {
log.Println(err)
}
rows.close()返回的错误是常规规则的唯一例外,最好捕获并检查所有数据库操作中的错误。如果rows.close()返回错误,我们也不清楚应该怎么做。记录错误消息或panic可能是唯一明智的选择,如果这样不合适,那么也许应该忽略错误。
Errors From QueryRow()
考虑以下获取单行数据的代码:
var name string
err = db.QueryRow("select name from users where id = ?", 1).Scan(&name)
if err != nil {
log.Fatal(err)
}
fmt.Println(name)
如果没有id=1的用户怎么办?然后结果中将没有行,.scan()不会将值扫描到name中。那会发生什么?
go定义了一个特殊的错误常量,称为sql.ErrNoRows,它是当结果为空时,QueryRow()的返回值。在大多数情况下,这需要作为一种特殊情况来处理。应用程序代码通常不会将空结果视为错误,如果不检查错误是否是这个特殊常量,则会导致预期之外的应用程序代码错误。
在调用scan()之前,查询中的错误将被延迟,然后从中返回。以上代码最好这样编写:
var name string
err = db.QueryRow("select name from users where id = ?", 1).Scan(&name)
if err != nil {
if err == sql.ErrNoRows {
// there were no rows, but otherwise no error occurred
} else {
log.Fatal(err)
}
}
fmt.Println(nam