如何访问未转换的驱动程序.sql 的值切片.行



我的目标是获取由 sql 驱动程序在其实现中反序列化的原始driver.Valuedriver.Rows.Next().我想处理从驱动程序返回的值到所需目标类型的转换,而不是依赖于内置于Rows.Scan的自动转换。请注意,这个问题不会询问您对是否使用Rows.Scan"应该"的意见。我不想使用它,我问是否有任何方法可以避免它。

一个有意义的答案根本不用Rows.Scan。使用未知列中说明的动态方法很糟糕:它调用 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

相关内容

最新更新