我的 golang sqlite 插入功能。我正在使用这个包"github.com/mattn/go-sqlite3"
func Insert(args ...string)(err error){
db, err:=sql.Open("sqlite3","sqlite.db")
if err !=nil {
return
}
q, err := db.Prepare(args[0])
if err !=nil{
return
}
_,err = q.Exec(args[1:]...)
return
}
main (){
err := Insert("INSERT INTO table(first,last) VALUES(?,?)","Nantha","nk")
if err !=nil{
fmt.Println(err.Error())
return
}
}
Run Code Online (Sandbox Code Playgroud)
我收到这个错误
无法在 q.Exec 的参数中使用 args (type []string) 作为 type []interface {}
错误非常清楚,该函数需要 type[]interface{}但您传递的是 type 的值[]string。在将其传递给 之前,您必须先转换[]string为。实现这一点的方法是循环遍历字符串并将每个字符串添加到.[]interface{}Execinterface{}
https://golang.org/doc/faq#convert_slice_of_interface
作为替代方法,您可以更改Insert参数类型。
func Insert(query string, args ...interface{}) (err error) {
db, err := sql.Open("sqlite3", "sqlite.db")
if err != nil {
return err
}
q, err := db.Prepare(query)
if err != nil {
return err
}
_, err = q.Exec(args...)
return err
}
func main() {
err := Insert("INSERT INTO table(first,last) VALUES(?,?)", "Nantha", "nk")
if err !=nil{
fmt.Println(err.Error())
return
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,您使用该database/sql包的方式不正确。从该包的函数/方法返回的许多对象需要关闭以释放底层资源。
*sql.DB对于returned by Open、*sql.Stmtreturned by Prepare、*sql.Rowsreturned byQuery等都是如此。
所以你的函数应该看起来更接近这样的东西:
func Insert(query string, args ...interface{}) (err error) {
db, err := sql.Open("sqlite3", "sqlite.db")
if err != nil {
return err
}
defer db.Close()
q, err := db.Prepare(query)
if err != nil {
return err
}
defer q.Close()
_, err = q.Exec(args...)
return err
}
Run Code Online (Sandbox Code Playgroud)
另请注意,它是可重用的,这意味着您不必每次需要与数据库通信时都sql.DB使用新实例。sql.Open
来自 Open 上的文档:
返回的数据库对于多个 goroutine 并发使用是安全的,并维护自己的空闲连接池。因此,Open 函数应该只调用一次。很少需要关闭数据库。
如果您继续按照目前的方式进行操作,DB每次调用时都打开一个新的Insert函数或任何其他需要与 进行通信的函数DB,那么您的程序的性能将比您只有一个函数DB并让您的函数重用它时表现更差。