Golang SQL-Fehler beim Versuch, einen neuen Benutzer zu erstellen

王林
Freigeben: 2024-02-12 23:39:10
nach vorne
1194 Leute haben es durchsucht

尝试创建新用户时出现 Golang SQL 错误

php-Editor Xiaoxin ist beim Erstellen eines neuen Benutzers mit Golang auf einen SQL-Fehler gestoßen. Dieser Fehler kann dazu führen, dass sich Benutzer nicht erfolgreich registrieren und der normale Betrieb der Website beeinträchtigt wird. Für dieses Problem müssen wir die Fehlerursache analysieren und eine Lösung finden. In diesem Artikel werden mehrere häufige Ursachen vorgestellt, die zu Golang-SQL-Fehlern führen können, und entsprechende Lösungen bereitgestellt, um Entwicklern dabei zu helfen, dieses Problem schnell zu lösen und den normalen Betrieb der Website sicherzustellen.

Frageninhalt

Ich habe diesen Fehler erhalten, als ich das Golang-Paket verwendet habe vipercobra 创建用户时,我在 new_user.go. Der Fehler ist wie folgt:

cannot use result (variable of type sql.result) as error value in return statement: sql.result does not implement error (missing method error)
Nach dem Login kopieren

Mein Code ist in zwei Dateien aufgeteilt, die miteinander kommunizieren. Hier ist die Baumhierarchie:

.
├── makefile
├── readme.md
├── cli
│   ├── config.go
│   ├── db-creds.yaml
│   ├── go.mod
│   ├── go.sum
│   ├── new_user.go
│   └── root.go
├── docker-compose.yaml
├── go.work
└── main.go
Nach dem Login kopieren

Um eine Verbindung zur Datenbank herzustellen, habe ich eine Yaml-Datei db-creds.yaml 来提取 config.go mit den Anmeldeinformationen erstellt. Keine Popup-Fehler hier:

config.go Dateien

package cli

import (
    "database/sql"
    "fmt"

    _ "github.com/go-sql-driver/mysql"
    _ "github.com/lib/pq"
    "github.com/spf13/viper"
)

// var dialects = map[string]gorp.dialect{
//  "postgres": gorp.postgresdialect{},
//  "mysql":    gorp.mysqldialect{engine: "innodb", encoding: "utf8"},
// }

// initconfig reads in config file and env variables if set
func initconfig() {
    if cfgfile != "" {
        viper.setconfigfile(cfgfile)
    } else {
        viper.addconfigpath("./")
        viper.setconfigname("db-creds")
        viper.setconfigtype("yaml")
    }

    // if a config file is found, read it in:
    err := viper.readinconfig()
    if err == nil {
        fmt.println("fatal error config file: ", viper.configfileused())
    }
    return
}

func getconnection() *sql.db {

    // make sure we only accept dialects that were compiled in.
    // dialect := viper.getstring("database.dialect")
    // _, exists := dialects[dialect]
    // if !exists {
    //  return nil, "", fmt.errorf("unsupported dialect: %s", dialect)
    // }

    // will want to create another command that will use a mapping
    // to connect to a preset db in the yaml file.
    dsn := fmt.sprintf("%s:%s@%s(%s)?parsetime=true",
        viper.getstring("mysql-5.7-dev.user"),
        viper.getstring("mysql-5.7-dev.password"),
        viper.getstring("mysql-5.7-dev.protocol"),
        viper.getstring("mysql-5.7-dev.address"),
    )
    viper.set("database.datasource", dsn)

    db, err := sql.open("msyql", viper.getstring("database.datasource"))
    if err != nil {
        fmt.errorf("cannot connect to database: %s", err)
    }

    return db
}
Nach dem Login kopieren

Der Fehler, den ich oben eingefügt habe, ist, wenn ich zurückkehre result 时出现的错误。我正在为 cobra 实现 flag 选项,以使用 -n 后跟 name, um anzuzeigen, dass der neue Benutzer hinzugefügt wird.

new_user.go Dateien

package cli

import (
    "log"

    "github.com/sethvargo/go-password/password"
    "github.com/spf13/cobra"
)

var name string

// newCmd represents the new command
var newCmd = &cobra.Command{
    Use:   "new",
    Short: "Create a new a user which will accommodate the individuals user name",
    Long:  `Create a new a user that will randomize a password to the specified user`,
    RunE: func(cmd *cobra.Command, args []string) error {

        db := getConnection()

        superSecretPassword, err := password.Generate(64, 10, 10, false, false)

        result, err := db.Exec("CREATE USER" + name + "'@'%'" + "IDENTIFIED BY" + superSecretPassword)
        if err != nil {
            log.Fatal(err)
        }

        // Will output the secret password combined with the user.
        log.Printf(superSecretPassword)

        return result <---- Error is here
    },
}

func init() {
    rootCmd.AddCommand(newCmd)

    newCmd.Flags().StringVarP(&name, "name", "n", "", "The name of user to be added")
    _ = newCmd.MarkFlagRequired("name")
}
Nach dem Login kopieren

Der Hauptzweck dieses Projekts ist dreifach: 1.) Einen neuen Benutzer erstellen, 2.) Erteilen Sie jedem Benutzer bestimmte Berechtigungen 3.) Löschen Sie sie. Das ist mein oberstes Ziel. Als ich Schritt für Schritt vorging, stieß ich auf diesen Fehler. Ich hoffe, jemand kann mir helfen. Ich bin neu bei Golang und habe vor etwa zwei Wochen damit begonnen, es zu verwenden.

Workaround

go gibt Ihnen einen sehr klaren Hinweis darauf, was vor sich geht. Das rune-Mitglied von cobra erwartet, dass sein Rückruf einen Fehler (oder Null, wenn erfolgreich) zurückgibt.

Hier geben Sie das Ergebnis zurück, bei dem es sich nicht um einen Fehler handelt, sondern um den spezifischen Typ, der von der SQL-Abfrage zurückgegeben wird. So sollte Ihre Funktion aussehen.

RunE: func(cmd *cobra.Command, args []string) error {

    db := getConnection()

    superSecretPassword, err := password.Generate(64, 10, 10, false, false)

    _, err := db.Exec("CREATE USER" + name + "'@'%'" + "IDENTIFIED BY" + superSecretPassword)
    if err != nil {
        // Don't Fatal uselessly, let cobra handle your error the way it
        // was designed to do it.
        return err
    }

    // Will output the secret password combined with the user.
    log.Printf(superSecretPassword)

    // Here is how you should indicate your callback terminated successfully.
    // Error is an interface, so it accepts nil values.
    return nil
}
Nach dem Login kopieren

Wenn Sie das Ergebnis des Befehls db.exec benötigen (was nicht der Fall zu sein scheint), müssen Sie alle erforderlichen Verarbeitungen im Cobra-Callback durchführen, da dieser nicht dafür ausgelegt ist, Werte an den Hauptthread zurückzugeben.

Fehlerbehandlung

Einige schlechte Praktiken, die mir in meinem Code bezüglich der Fehlerbehandlung aufgefallen sind:

  • Wenn die Go-Funktion einen Fehler zurückgibt, geraten Sie nicht in Panik und beenden Sie das Programm nicht, wenn etwas Unerwartetes passiert (wie Sie es mit log.fatal getan haben). Verwenden Sie stattdessen diese Fehlerrückgabe, um den Fehler an den Hauptthread weiterzugeben und ihn entscheiden zu lassen, was zu tun ist.

  • Wenn andererseits etwas schief geht, geben Sie keine Ergebnisse zurück. Wenn dies fehlschlägt, sollte Ihre Funktion getconnection in der Lage sein, einen Fehler zurückzugeben: func getconnection() (*sql.db, Fehler). Sie sollten diesen Fehler dann in der Funktion getconnection 函数应该能够返回错误:func getconnection() (*sql.db, error)。然后,您应该在 rune behandeln, anstatt ihn nur zu protokollieren und normal zu behandeln.

Das obige ist der detaillierte Inhalt vonGolang SQL-Fehler beim Versuch, einen neuen Benutzer zu erstellen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!