Heim >Backend-Entwicklung >Golang >Gorm gibt einen Scannerfehler für den benutzerdefinierten Zeichenfolgentyp zurück

Gorm gibt einen Scannerfehler für den benutzerdefinierten Zeichenfolgentyp zurück

王林
王林nach vorne
2024-02-11 18:21:211157Durchsuche

Gorm 在自定义字符串类型上返回扫描仪错误

Einführung in die Banane des PHP-Editors: Wenn Sie in Gorm versuchen, einen Scanvorgang für einen benutzerdefinierten Zeichenfolgentyp durchzuführen, können Fehler auftreten. Dieses Problem kann dazu führen, dass der Scanner die Zeichenfolge nicht richtig analysiert, was zu Programmfehlern führt. Dies liegt daran, dass Gorm standardmäßig die Methode „Scan“ verwendet, um Felder vom Typ „String“ zu scannen. Bei benutzerdefinierten String-Typen verarbeitet die Methode „Scan“ dies jedoch möglicherweise nicht korrekt. Die Lösung für dieses Problem besteht darin, die Zeichenfolge mithilfe der Methode „Value“ manuell zu analysieren, um sicherzustellen, dass das Programm ordnungsgemäß ausgeführt wird. Auf diese Weise können Sie Probleme mit Scannerfehlern bei der Verwendung von Gorm vermeiden.

Frageninhalt

Ich habe folgende Entitäten geschrieben:

type datacategory string

const (
    datacategory1 datacategory = "category1"
    datacategory2 datacategory = "category2"
)

type data struct {
    name            string         `json:"name"`
    categories      []datacategory `json:"category" gorm:"type:text[]"`
}

Ich habe manuell eine Zeile in der Datenbank erstellt und den Array-Typ „Kategorien“ mit Kategorie1 und Kategorie2 gefüllt.

Aber beim Auslesen der Daten tritt folgender Fehler auf:

sql: scan error on column index 19, name "category": unsupported scan, storing driver.value type string into type *[]datacategory

Beispielwertmethode:

func (s DataCategorySlice) Value() (driver.Value, error) {
    if s == nil {
        return nil, nil
    }
    if len(s) == 0 {
        return "{}", nil
    }

    v := []string{}
    for _, dc := range s {
        v = append(v, string(dc))
    }
    result := fmt.Sprintf("{%s}", strings.Join(v, ","))
    return result, nil
}

Problemumgehung

Das folgende Beispiel geht davon aus, dass Sie Postgresql als RDBMS verwenden und der datacategory-Wert keine Kommas oder einfache Anführungszeichen ohne Escapezeichen enthält.

// declare the custom type
type datacategoryslice []datacategory
// implement driver.valuer to encode the value into the
// correct format that is accepted by the target rdbms
func (s datacategoryslice) value() (driver.value, error) {
    if s == nil {
        return nil, nil
    }
    if len(s) == 0 {
        return []byte(`{}`), nil
    }

    v := []byte(`{`)
    for i := range s {
        v = append(v, s[i]...)
        v = append(v, ',')
    }
    v[len(v)-1] = '}' // replace last comma with closing brace
    return v, nil
}
// implement scanner to decode the raw source
// value as retrieved from the database
func (s *datacategoryslice) scan(src any) error {
    var data []byte
    switch v := src.(type) {
    case []byte:
        data = v
    case string:
        data = []byte(v)
    case nil:
        return nil
    default:
        return fmt.errorf("unsupported type: %t", src)
    }
    if len(data) == 0 {
        return nil
    }
    data = data[1:len(data)-1] // remove surrounding braces
    for _, v := range bytes.split(data, []byte{','}) {
        *s = append(*s, datacategory(v))
    }
    return nil
}

Oder, wenn von value() (driver.value, error) 返回 <code>[]byte 不起作用,例如它会导致 “错误:格式错误的数组文字:8778596cdf2dd446fb8c439c52c90b59 (sqlstate 22p02)”,那么您可以尝试使用 string als Rückgabetyp.

Beispiel von @kozhioyrin

// implement driver.Valuer to encode the value into the
// correct format that is accepted by the target RDBMS
func (s DataCategorySlice) Value() (driver.Value, error) {
    if s == nil {
        return nil, nil
    }
    if len(s) == 0 {
        return "{}", nil
    }

    v := []string{}
    for _, dc := range s {
        v = append(v, string(dc))
    }
    result := fmt.Sprintf("{%s}", strings.Join(v, ","))
    return result, nil
}

Das obige ist der detaillierte Inhalt vonGorm gibt einen Scannerfehler für den benutzerdefinierten Zeichenfolgentyp zurück. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen