Golang中如何访问Statement中的值
Golang中如何访问Statement中的值
package main
import (
"database/sql"
"fmt"
_ "vNext/go_ibm_db"
)
func main() {
con := "HOSTNAME=localhost;PORT=50000;DATABASE=dbname;UID=uname;PWD=password"
db, err := sql.Open("go_ibm_db", con)
if err != nil {
fmt.Println(err)
}
db.Exec("Create table dbtype2(a int,c float)")
st,err:=db.Prepare("Insert into dbtype2(a,c) values(?,?)")
if err != nil{
fmt.Println(err)
}
st.Query(12,3.45)
}
我想要访问st中的一个变量(语句句柄)。但当我尝试访问它时,提示该变量未导出。是否有其他方法可以访问它。
谢谢。
更多关于Golang中如何访问Statement中的值的实战教程也可以访问 https://www.itying.com/category-94-b0.html
引用 akhilravuri:
访问其中未导出的变量
不。
更多关于Golang中如何访问Statement中的值的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
当我们调用 db.Prepare() 时,它会在内部创建一个语句句柄,然后运行 SQL 接口。有没有办法将该句柄传递给应用程序?
抱歉,应该是
func (db *DB) Exec(query string, args ...interface{}) (Result, error) {
return db.ExecContext(context.Background(), query, args...)
}
database/sql 包中的 Exec 函数
type Stmt struct {
// Immutable:
db *DB // where we came from
query string // that created the Stmt
stickyErr error // if non-nil, this error is returned for all operations
closemu sync.RWMutex // held exclusively during close, for read otherwise.
cg stmtConnGrabber
cgds *driverStmt
parentStmt *Stmt
mu sync.Mutex // protects the rest of the fields
closed bool
css []connStmt
lastNumClosed uint64
}
st 是一个通过 db.Prepare() 返回的 Stmt 对象 有没有办法访问其中未导出的变量?
在Go语言的database/sql包中,Stmt类型的内部字段(如语句句柄)通常被设计为未导出字段,这是出于封装和抽象数据库驱动实现的考虑。不过,你可以通过类型断言来访问特定驱动提供的导出方法或字段,前提是驱动支持。
对于go_ibm_db驱动,Stmt的实际类型可能是*go_ibm_db.OCI8Stmt(具体类型名可能因驱动版本而异)。你需要检查驱动文档或源代码,确认是否有导出字段或方法允许访问语句句柄。以下是一个示例方法,假设驱动提供了GetStmtHandle方法(实际方法名可能不同):
package main
import (
"database/sql"
"fmt"
"reflect"
_ "vNext/go_ibm_db"
)
func main() {
con := "HOSTNAME=localhost;PORT=50000;DATABASE=dbname;UID=uname;PWD=password"
db, err := sql.Open("go_ibm_db", con)
if err != nil {
fmt.Println(err)
return
}
defer db.Close()
// 创建表并准备语句
_, err = db.Exec("CREATE TABLE dbtype2(a INT, c FLOAT)")
if err != nil {
fmt.Println(err)
return
}
st, err := db.Prepare("INSERT INTO dbtype2(a, c) VALUES(?, ?)")
if err != nil {
fmt.Println(err)
return
}
defer st.Close()
// 使用反射检查 st 的实际类型
fmt.Printf("stmt type: %v\n", reflect.TypeOf(st))
// 尝试类型断言到驱动特定类型
if driverStmt, ok := st.(interface{ GetStmtHandle() interface{} }); ok {
handle := driverStmt.GetStmtHandle()
fmt.Printf("Statement handle: %v\n", handle)
} else {
fmt.Println("驱动未提供 GetStmtHandle 方法")
}
// 执行插入操作
_, err = st.Exec(12, 3.45)
if err != nil {
fmt.Println(err)
}
}
如果驱动没有提供直接访问句柄的方法,你可能需要修改驱动代码或使用反射强制访问未导出字段(不推荐,因为可能破坏封装和兼容性)。例如,使用反射访问假设的stmtHandle字段:
// 注意:此方法依赖于驱动内部结构,可能随版本变化而失效
v := reflect.ValueOf(st).Elem()
if v.Kind() == reflect.Struct {
f := v.FieldByName("stmtHandle") // 字段名需根据驱动实际名称调整
if f.IsValid() && f.CanInterface() {
handle := f.Interface()
fmt.Printf("Statement handle: %v\n", handle)
}
}
在实际应用中,建议优先查阅go_ibm_db驱动的文档或源代码,确认支持的接口。如果驱动未设计导出句柄,可能需要通过其他方式(如驱动提供的特定函数)实现你的需求。


