我写的代码如下。
rows, err := s.db.QueryContext(context.TODO(), "select * from mytable")
if err != nil {
log.WithFields(log.Fields{
"query": queryString,
}).Errorln("failed to query, ", err)
return err
}
resultString, err := getResultString(rows)
我还添加了
getResultString
,如下所示。
func getResultString(rows *sql.Rows) (*string, error) {
defer rows.Close()
var result string
if rows.Next() {
if err := rows.Scan(&result); err != nil {
return nil, fmt.Errorf("scan err, %v", err)
} else {
return &result, nil
}
}
return nil, fmt.Errorf("query err, %v", rows.Err())
}
此代码是根据gosnowflake中如何使用查询的示例编写的。
运行应用程序时,有时会出现如下内存问题。
2024-05-14T13:42:08.689+09:00 panic: runtime error: invalid memory address or nil pointer dereference
2024-05-14T13:42:08.689+09:00 panic: runtime error: invalid memory address or nil pointer dereference
2024-05-14T13:42:08.689+09:00 [signal SIGSEGV: segmentation violation code=0x1 addr=0x38 pc=0x7d8848]
2024-05-14T13:42:08.689+09:00 goroutine 143 [running]:
2024-05-14T13:42:08.689+09:00 github.com/snowflakedb/gosnowflake.(*snowflakeRows).Close(0x10?)
2024-05-14T13:42:08.689+09:00 /home/ec2-user/go/pkg/mod/github.com/snowflakedb/[email protected]/rows.go:67 +0x18
2024-05-14T13:42:08.689+09:00 database/sql.(*Rows).close.func1()
2024-05-14T13:42:08.689+09:00 /usr/lib/golang/src/database/sql/sql.go:3287 +0x34
2024-05-14T13:42:08.689+09:00 database/sql.withLock({0xb788d8, 0x40033dbc20}, 0x40008ecf48)
2024-05-14T13:42:08.689+09:00 /usr/lib/golang/src/database/sql/sql.go:3405 +0x7c
2024-05-14T13:42:08.689+09:00 database/sql.(*Rows).close(0x4000097980, {0x0, 0x0})
2024-05-14T13:42:08.689+09:00 /usr/lib/golang/src/database/sql/sql.go:3286 +0x130
在努力解决这个问题之后,但我怀疑这一点。
正如您在上面所看到的,我在函数中创建了行并将它们作为参数传递给另一个函数 (
getResultString
)。虽然这个过程,我认为可能会发生一些内存损坏,因为我看到的代码示例是所有逻辑都包含在一个函数中,这与我的代码形成对比。
所以我怀疑将
row
传递给其他函数可能会导致潜在的问题。
我的怀疑合理吗?否则,您有什么解决问题的建议吗?
谢谢,
实际上
Close()
在这里什么也没做,请参阅此链接
https://github.com/snowflakedb/gosnowflake/blob/c355711dbd1f9ab10dfbfdcdd194656c23abb45d/rows.go#L76
并且您的代码没有问题,这主要是来自
github.com/snowflakedb/gosnowflake
库的错误。
还请继续重构getResultString(rows *sql.Rows)
,如下所示:
func getResultString(rows *sql.Rows) (*string, error) {
if err = rows.Next(); err != nil {
// Next failed with an error, you can wrap the error using errors.Join
return nil,err
}
var result string
if err = rows.Scan(&result); err != nil {
// scan fails
return nil,err
}
return &result,nil
}