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é

王林
王林avant
2024-02-11 18:21:211195parcourir

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[]"`
}

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

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
}

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
// 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
}

Ou, si de value() (driver.value, error) 返回 <code>[]byte 不起作用,例如它会导致 “错误:格式错误的数组文字:8778596cdf2dd446fb8c439c52c90b59 (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
}

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer