-1

我的目标是获取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)
}
4

1 回答 1

1

正常的解决方案是实现自己的sql.Scanner. 但这确实有用rows.Scan,所以它违反了你不使用的神秘要求rows.Scan

如果您真的rows.Scan必须driver.Value避免rows.Scan.

于 2019-09-09T20:46:30.070 回答