我的目标是获取原始 driver.Value
值,由 sql 驱动程序在其 driver.Rows.Next()
实现中反序列化。 我想处理从驱动程序返回的值到所需目标类型的转换,而不是依赖 Rows.Scan
中内置的自动转换。请注意这个问题不会询问您是否“应该”使用 Rows.Scan
的意见。我不想使用它,我想请问是否有任何方法可以避免它。
有意义的答案根本不使用 Rows.Scan
。 Working with Unknown Columns 中说明的动态方法很糟糕:它调用 Scan 的所有开销并破坏源列的类型信息,而不是将实际的 driver.Value
分解为 SqlBytes
。
以下 hack 有效,但依赖于 sql.Rows.Next()
使用我想要的未转换值填充内部字段 lastcols
的内部实现细节:
vpRows := reflect.ValueOf(rows) // rows is a *sql.Rows
vRows := reflect.Indirect(vpRows) // now we have the sql.Rows struct
mem := vRows.FieldByName("lastcols") // unexported field lastcols
unsafeLastCols := unsafe.Pointer(mem.UnsafeAddr()) // Evil
plastCols := (*[]driver.Value)(unsafeLastCols) // But effective
for rows.Next() {
rowVals := *plastCols
fmt.Println(rowVals)
}
最佳答案
正常的解决方案是实现自己的 sql.Scanner
.但这确实使用了 rows.Scan
,因此它违反了您不使用 rows.Scan
的神秘要求。
如果您真的必须避免rows.Scan
,您需要编写自己的驱动程序实现(可能包装现有的驱动程序),它提供对driver.Value
的访问> 没有 rows.Scan
的值。
关于go - 如何访问未转换的 driver.Value sql.Rows slice ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57859946/