🐛 fix(sqlserver): 修正 uniqueidentifier 展示为十六进制字节

- 查询值规整新增 uniqueidentifier 识别并复用 go-mssqldb GUID 格式化
- 避免 SQL Server 查询结果把 GUID 展示为原始 0x 字节串
- 补充 uniqueidentifier 原始字节回归测试并覆盖驱动返回值路径

Fixes #381
This commit is contained in:
Syngnat
2026-04-17 18:10:51 +08:00
parent e56a72eb9f
commit 4fd679ce42
2 changed files with 36 additions and 0 deletions

View File

@@ -11,6 +11,8 @@ import (
"time"
"unicode"
"unicode/utf8"
mssql "github.com/microsoft/go-mssqldb"
)
const (
@@ -195,6 +197,12 @@ func bytesToDisplayValue(b []byte, databaseTypeName string) interface{} {
}
dbType := strings.ToUpper(strings.TrimSpace(databaseTypeName))
if isSQLServerUniqueIdentifierType(dbType) {
var guid mssql.UniqueIdentifier
if err := guid.Scan(b); err == nil {
return guid.String()
}
}
if isBitLikeDBType(dbType) {
if u, ok := bytesToUint64(b); ok {
// JS number precision is limited; keep large bitmasks as string.
@@ -230,6 +238,10 @@ func bytesToReadableString(b []byte) interface{} {
return "0x" + hex.EncodeToString(b)
}
func isSQLServerUniqueIdentifierType(typeName string) bool {
return typeName == "UNIQUEIDENTIFIER"
}
func isBitLikeDBType(typeName string) bool {
if typeName == "" {
return false

View File

@@ -5,6 +5,8 @@ import (
"fmt"
"testing"
"time"
mssql "github.com/microsoft/go-mssqldb"
)
type duckMapLike map[any]any
@@ -50,6 +52,28 @@ func TestNormalizeQueryValueWithDBType_ByteFallbacks(t *testing.T) {
}
}
func TestNormalizeQueryValueWithDBType_UniqueIdentifierBytes(t *testing.T) {
var guid mssql.UniqueIdentifier
if err := guid.Scan("6F9619FF-8B86-D011-B42D-00C04FC964FF"); err != nil {
t.Fatalf("构造 UniqueIdentifier 失败: %v", err)
}
rawValue, err := guid.Value()
if err != nil {
t.Fatalf("UniqueIdentifier.Value() 失败: %v", err)
}
rawBytes, ok := rawValue.([]byte)
if !ok {
t.Fatalf("期望驱动值为 []byte实际=%T", rawValue)
}
got := normalizeQueryValueWithDBType(rawBytes, "uniqueidentifier")
if got != "6F9619FF-8B86-D011-B42D-00C04FC964FF" {
t.Fatalf("uniqueidentifier 期望展示为 GUID 文本,实际=%v(%T)", got, got)
}
}
func TestNormalizeQueryValueWithDBType_MapAnyAnyForJSON(t *testing.T) {
input := duckMapLike{
"id": int64(1),