使用“ database/sql
”,sql.DB.Exec()
用于不返回行(insert, delete, update
)的查询,而sql.DB.Query(
)用于返回行({{1} }。
假定您有一个要执行的传入查询字符串,但是您不知道该查询是否打算返回行。
您能想到一种找出使用Exec还是Query的方法吗?
答案 0 :(得分:1)
在任何情况下,都不要尝试解析SQL,因为它很容易破解。如果不确定,只需使用Query
,Query
应该能够很好地处理C_UD并在这种情况下返回空结果集。 Query
和Exec
应该具有完全相同的效果,并且它们的响应方式不同。仅当您的API用户明确不需要结果时,才使用Exec
。
答案 1 :(得分:0)
您的问题并不像乍看起来那样简单。
问题与pgsql / mysql / sqlite / other无关,而是与任何通用数据库驱动器有关。
因此答案必须在database/sql/driver
中。
让我们走的更远。
sql/driver
。接口:Queryer
/ QueryerContext
和Execer
/ ExecerContext
模块sql/driver
定义了接口:
Queryer
/ QeueryerContext
-具有(*DB).Query
Execer
/ ExecerContext
-代表(*DB).Exec
Pinger
请注意,每个接口在文档中均被描述为“,可以由Conn实现的可选接口”
这意味着可以在没有Query
和/或Exec
的情况下实现sql驱动程序。
让我们尝试实现不能Query
和Exec
不能运行的正确数据库驱动程序:https://play.golang.org/p/sZiigEghphE
package main
import (
"database/sql"
"database/sql/driver"
"log"
)
type expdrv struct{}
type expconn struct{}
// sql.Driver implementation
func (*expdrv) Open(name string) (driver.Conn, error) {
return &expconn{}, nil
}
// driver.Conn implementation
func (c *expconn) Prepare(query string) (driver.Stmt, error) {
return nil, nil
}
func (c *expconn) Close() error {
return nil
}
func (c *expconn) Begin() (driver.Tx, error) {
return nil, nil
}
func main() {
sql.Register("drvexp", &expdrv{})
log.Printf("Registred drivers: %v\n", sql.Drivers())
db, err := sql.Open("drvexp", "")
log.Printf("sql.Open() success: %v, error: %v", db != nil, err)
log.Println("db.Close() error:", db.Close())
}
2009/11/10 23:00:00 Registred drivers: [drvexp] 2009/11/10 23:00:00 sql.Open() success: true, error: 2009/11/10 23:00:00 db.Ping() success: true 2009/11/10 23:00:00 db.Close() success: true 2009/11/10 23:00:00 db.Ping() result: sql: database is closed
有效!
此Driver
实现是:
database/sql
角度来看是正确的Query
和Exec
(尝试将引发恐慌)Ping()
Exec
或Query
让我们添加Exec
:
// driver.Result & driver.Execer
type expresult struct{}
func (*expconn) Exec(query string, args []driver.Value) (driver.Result, error) {
return &expresult{}, nil
}
func (*expresult) LastInsertId() (int64, error) {
return 0, nil
}
func (*expresult) RowsAffected() (int64, error) {
return 0, nil
}
将允许:
_, err = db.Exec("BYE")
fmt.Println("db.Exec() success:", err == nil) // Outputs: true
呼叫Query/QueryContext
和/或Exec/ExecContext
的能力是可选的
这些方法的行为在驱动程序之间可能会发生很大的变化
通常情况下,不存在正确答案
对于特定情况(使用特定驱动程序):
db.Query
适用于大多数情况Query
在没有实验验证的情况下确实可以工作谢谢您的关注!
我想这是最终答案。