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