Cannot use args (type []string) as type []interface {}
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.
Related videos on Youtube
Comments
-
Ram almost 2 years
my golang sqlite insert function. i'm using this package
"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 } }
i'm getting this error
cannot use args (type []string) as type []interface {} in argument to q.Exec
-
mkopriva over 4 yearsYou have to convert
[]string
to[]interface{}
before passing it toExec
. And the way to do that is to loop over the strings and add each one to a new slice of interface{}. -
Peter over 4 years
-
Ram over 4 yearsany other solution without using loop
-
mkopriva over 4 yearsNo, there isn't.
-
Volker over 4 years@mkopriva He could use a recursive solution which formally isn't a loop ;-)
-
-
Ram over 4 yearsv:= []interface{}{"nantha","nk"} -> Insert(q,v) i'm getting unsupported type []interface {}, a slice of interface
-
mkopriva over 4 years@Nantha You don't need to do that,
Insert(q, "Nantha", "nk")
will still work, even after you change theInsert
toInsert(query string, args ...interface{})
-
mkopriva over 4 years@Nantha and if you want to use
v := []interface{}{"nantha","nk"}
, you can do it like thisInsert(q, v...)
. -
Ram over 4 yearsit's working :) thank you so much