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.
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 }
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
不起作用,例如它会导致 “错误:格式错误的数组文字:<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 }
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!