将结构接口传递给 sqlite exec
Pass struct interface to sqlite exec
在 Go 中,我试图将 interface{}
从 go-sqlite3
传递给 statement.Exec()
函数。我确定这是一个已解决的问题,但我无法弄清楚。
基本上我有一个 struct
行数据,我想将其传递给一个函数,该函数将把它插入到 sqlite 数据库中。问题是我希望能够以编程方式控制 statement.Exec()
函数
中的内容
摘录如下:
type hostRows struct {
domain string
}
type clientRows struct {
name string
}
func main() {
...
data := hostRows{domain: "dom.com"}
insertRow(sqliteDatabase, data)
data2 := clientRows{name: "bob"}
insertRow(sqliteDatabase, data2)
...
}
func insertRow(db *sql.DB, row interface{}) {
insertSQL := "INSERT INTO table(col) VALUES (?)"
statement, _ := db.Prepare(insertSQL)
statement.Exec(row) // here's the issue, how can I extract the element in the interface to pass it to the function for Exec to understand
}
我知道在这个例子中,我可以将行类型硬编码到结构和类型 statement.Exec(row.(hostRows).domain)
,但现在代码将在传递客户端结构时中断。
这里是Exec
函数的减速度
func (s *Stmt) Exec(args ...interface{}) (Result, error)
我试过 reflect
,但到目前为止它对我不起作用。
我目前唯一的解决方案是使用 switch
条件,它可以检查并准备 Exec
的正确命令,但这并不狡猾。
type hostRows struct {
domain string
}
type clientRows struct {
name string
}
func main() {
...
data := hostRows{domain: "dom.com"}
insertRow(sqliteDatabase, 1, data)
data2 := clientRows{name: "bob"}
insertRow(sqliteDatabase, 2, data2)
...
}
func insertRow(db *sql.DB, i int, row interface{}) {
insertSQL := "INSERT INTO table(col) VALUES (?)"
statement, _ := db.Prepare(insertSQL)
// This basically could be a working solution, but I'm sure there is a better one
switch i {
case 1:
data := row.(hostRows)
statement.Exec(data.domain)
case 2:
data := row.(clientRows)
statement.Exec(data.name)
}
}
编辑:更正了 INSERT 语句;忘记专栏。将 statement.Exec(row.domain)
更正为 statement.Exec(row.(hostRows).domain)
edit2:添加了第二个例子
请记住,为了 reflect.Interface()
工作,您 必须 导出字段。要使用反射实现你想要的,你可以尝试这样的事情:
type hostRows struct {
//Should export field to read it using reflect.Value.Interface()
Domain string
}
type clientRows struct {
//Should export field to read it using reflect.Value.Interface()
Name string
}
func insertRow(db *sql.DB, i int, row interface{}) {
rv := reflect.ValueOf(row)
var args []interface{}
for i := 0; i < rv.NumField(); i++ {
args = append(args, rv.Field(i).Interface())
}
db.Exec("Insert Satement...", args...)
}
在 Go 中,我试图将 interface{}
从 go-sqlite3
传递给 statement.Exec()
函数。我确定这是一个已解决的问题,但我无法弄清楚。
基本上我有一个 struct
行数据,我想将其传递给一个函数,该函数将把它插入到 sqlite 数据库中。问题是我希望能够以编程方式控制 statement.Exec()
函数
摘录如下:
type hostRows struct {
domain string
}
type clientRows struct {
name string
}
func main() {
...
data := hostRows{domain: "dom.com"}
insertRow(sqliteDatabase, data)
data2 := clientRows{name: "bob"}
insertRow(sqliteDatabase, data2)
...
}
func insertRow(db *sql.DB, row interface{}) {
insertSQL := "INSERT INTO table(col) VALUES (?)"
statement, _ := db.Prepare(insertSQL)
statement.Exec(row) // here's the issue, how can I extract the element in the interface to pass it to the function for Exec to understand
}
我知道在这个例子中,我可以将行类型硬编码到结构和类型 statement.Exec(row.(hostRows).domain)
,但现在代码将在传递客户端结构时中断。
这里是Exec
函数的减速度
func (s *Stmt) Exec(args ...interface{}) (Result, error)
我试过 reflect
,但到目前为止它对我不起作用。
我目前唯一的解决方案是使用 switch
条件,它可以检查并准备 Exec
的正确命令,但这并不狡猾。
type hostRows struct {
domain string
}
type clientRows struct {
name string
}
func main() {
...
data := hostRows{domain: "dom.com"}
insertRow(sqliteDatabase, 1, data)
data2 := clientRows{name: "bob"}
insertRow(sqliteDatabase, 2, data2)
...
}
func insertRow(db *sql.DB, i int, row interface{}) {
insertSQL := "INSERT INTO table(col) VALUES (?)"
statement, _ := db.Prepare(insertSQL)
// This basically could be a working solution, but I'm sure there is a better one
switch i {
case 1:
data := row.(hostRows)
statement.Exec(data.domain)
case 2:
data := row.(clientRows)
statement.Exec(data.name)
}
}
编辑:更正了 INSERT 语句;忘记专栏。将 statement.Exec(row.domain)
更正为 statement.Exec(row.(hostRows).domain)
edit2:添加了第二个例子
请记住,为了 reflect.Interface()
工作,您 必须 导出字段。要使用反射实现你想要的,你可以尝试这样的事情:
type hostRows struct {
//Should export field to read it using reflect.Value.Interface()
Domain string
}
type clientRows struct {
//Should export field to read it using reflect.Value.Interface()
Name string
}
func insertRow(db *sql.DB, i int, row interface{}) {
rv := reflect.ValueOf(row)
var args []interface{}
for i := 0; i < rv.NumField(); i++ {
args = append(args, rv.Field(i).Interface())
}
db.Exec("Insert Satement...", args...)
}