Maison > développement back-end > Golang > Gorm renvoie une erreur du scanner sur le type de chaîne personnalisé

Gorm renvoie une erreur du scanner sur le type de chaîne personnalisé

王林
Libérer: 2024-02-11 18:21:21
avant
1155 Les gens l'ont consulté

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

introduction banane de l'éditeur php : Dans Gorm, lorsque vous essayez d'effectuer une opération d'analyse sur un type de chaîne personnalisé, vous pouvez rencontrer des erreurs. Ce problème peut empêcher le scanner d'analyser correctement la chaîne, ce qui entraînera des erreurs de programme. En effet, Gorm utilise la méthode « Scan » par défaut pour analyser les champs de type chaîne, mais pour les types de chaîne personnalisés, la méthode « Scan » peut ne pas la gérer correctement. La solution à ce problème consiste à utiliser la méthode « Value » pour analyser manuellement la chaîne afin de garantir que le programme s'exécute correctement. De cette façon, vous pouvez éviter de rencontrer des problèmes d'erreurs de scanner lors de l'utilisation de Gorm.

Contenu de la question

J'ai écrit les entités suivantes :

type datacategory string

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

type data struct {
    name            string         `json:"name"`
    categories      []datacategory `json:"category" gorm:"type:text[]"`
}
Copier après la connexion

J'ai créé manuellement une ligne dans la base de données et rempli le type de tableau de catégories avec catégorie1 et catégorie2.

Mais l'erreur suivante se produit lors de la lecture des données :

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

Exemple de méthode de valeur :

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
}
Copier après la connexion

Solution de contournement

L'exemple suivant suppose que vous utilisez postgresql comme rdbms et que la valeur datacategory ne contient pas de virgules ni de guillemets simples sans échappement.

// declare the custom type
type datacategoryslice []datacategory
Copier après la connexion
// 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
}
Copier après la connexion
// 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
}
Copier après la connexion

Ou, si de value() (driver.value, error) 返回 <code>[]byte 不起作用,例如它会导致 “错误:格式错误的数组文字:<hex 字段值的表示形式> (sqlstate 22p02)”,那么您可以尝试使用 string comme type de retour.

Exemple de @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
}
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal