The error is pretty clear, the function expects type []interface{}
but you're passing in a value of type []string
. You have to first convert []string
to []interface{}
before passing it to Exec
. And the way to do that is to loop over the strings and add each one to a new slice of interface{}
.
https://golang.org/doc/faq#convert_slice_of_interface
As an alternative approach, you can change the Insert
argument types.
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
}
}
Please note that you're using the database/sql
package incorrectly. Many of the objects returned from that package's functions/methods need to be closed to release the underlying resources.
This is true for *sql.DB
returned by Open
, *sql.Stmt
returned by Prepare
, *sql.Rows
returned by Query
, etc.
So your function should look closer to something like this:
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
}
Also note that sql.DB
is reusable, that means that you don't have to sql.Open
a new instance every time you need to talk to the database.
From the docs on Open:
The returned DB is safe for concurrent use by multiple goroutines and
maintains its own pool of idle connections. Thus, the Open function
should be called just once. It is rarely necessary to close a DB.
If you keep doing it the way you're doing it, openning a new DB
every time you call Insert
or any other function that needs to talk to the DB
, your program will perform worse than if you had a single DB
and have your functions reuse that.