我的目标是获取driver.Value由 sql 驱动程序在其实现中反序列化的原始值driver.Rows.Next()。我想处理从驱动程序返回的值到所需目标类型的转换,而不是依赖于Rows.Scan. 请注意,此问题不会询问您对是否Rows.Scan使用“应该”的意见。我不想使用它,我问是否有任何方法可以避免它。
Rows.Scan一个有意义的答案根本不使用。使用未知列中说明的动态方法很糟糕:它调用 Scan 的所有开销并破坏源列的类型信息,而不是将实际driver.Value的 s 分解为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)
}