Golang中传递给Query的语句应该是只读的吗?

Golang中传递给Query的语句应该是只读的吗? 是否期望传递给 database/sqlDB.QueryConn.Query 等的 SQL 语句是只读的,即不修改数据库的状态?“查询”一词暗示了这种期望,但有些 SQL 结构在返回行的同时也会修改数据库,例如 SQLite(以及 PostgreSQL,我认为?)中的 DELETE FROM ... RETURNING ...,而针对 database/sql 接口运行这些语句的唯一方式似乎就是使用 Query。

func main() {
    fmt.Println("hello world")
}

更多关于Golang中传递给Query的语句应该是只读的吗?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

据我所知,对于任何需要从表中返回数据的操作,都必须使用 *.Query

而对于任何返回“受影响列”计数的操作,则使用 *.Exec

更多关于Golang中传递给Query的语句应该是只读的吗?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在 Go 的 database/sql 包中,Query 方法确实主要用于执行返回行的只读操作,但技术上并不强制要求 SQL 语句是只读的。Query 适用于任何返回结果集的语句,包括像 DELETE ... RETURNING 这样在修改数据的同时返回行的语句。然而,最佳实践是:

  1. 使用 Exec 进行不返回行的数据修改操作(如 INSERTUPDATEDELETE 不带 RETURNING)。
  2. 使用 Query 仅当需要处理返回的结果集时,即使语句会修改数据库状态(如 DELETE ... RETURNING)。

示例:使用 Query 执行 DELETE ... RETURNING(在支持它的数据库如 PostgreSQL 中):

rows, err := db.Query("DELETE FROM users WHERE active = false RETURNING id, name")
if err != nil {
    log.Fatal(err)
}
defer rows.Close()

for rows.Next() {
    var id int
    var name string
    if err := rows.Scan(&id, &name); err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Deleted user: ID=%d, Name=%s\n", id, name)
}
if err := rows.Err(); err != nil {
    log.Fatal(err)
}

注意:对于不返回结果集的修改操作,应优先使用 Exec,以避免不必要的资源开销。例如:

result, err := db.Exec("UPDATE users SET active = true WHERE id = $1", 123)
if err != nil {
    log.Fatal(err)
}
affected, _ := result.RowsAffected()
fmt.Printf("Updated %d rows\n", affected)
回到顶部