Maison  >  Article  >  développement back-end  >  Erreur Golang SQL lors de la tentative de création d'un nouvel utilisateur

Erreur Golang SQL lors de la tentative de création d'un nouvel utilisateur

王林
王林avant
2024-02-12 23:39:101216parcourir

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

L'éditeur php Xiaoxin a rencontré une erreur SQL lors de la création d'un nouvel utilisateur à l'aide de Golang. Cette erreur peut empêcher les utilisateurs de s'inscrire correctement et perturber le fonctionnement normal du site Web. Pour ce problème, nous devons analyser la cause de l’erreur et trouver une solution. Cet article présentera plusieurs causes courantes pouvant provoquer des erreurs Golang SQL et fournira les solutions correspondantes pour aider les développeurs à résoudre rapidement ce problème et à assurer le fonctionnement normal du site Web.

Contenu de la question

J'ai reçu cette erreur lors de l'utilisation du package golang vipercobra 创建用户时,我在 new_user.go. L'erreur est la suivante :

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

Mon code est découpé en deux fichiers qui communiquent entre eux, voici l'arborescence :

.
├── 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

Pour me connecter à la base de données, j'ai créé un fichier yaml db-creds.yaml 来提取 config.go avec les identifiants. Aucune erreur de popup ici :

config.go Fichiers

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
}

L'erreur que je mets en haut, c'est lorsque je reviens result 时出现的错误。我正在为 cobra 实现 flag 选项,以使用 -n 后跟 name pour indiquer le nouvel utilisateur en cours d'ajout.

new_user.go Fichiers

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")
}

L'objectif principal de ce projet est triple : 1.) Créez un nouvel utilisateur, 2.) Accordez des autorisations spécifiques à n'importe quel utilisateur 3.) Supprimez-les. C'est mon objectif ultime. En procédant étape par étape, j'ai rencontré cette erreur. J'espère que quelqu'un pourra m'aider. Je suis nouveau sur Golang, j'ai commencé à l'utiliser il y a environ deux semaines.

Workaround

go vous donne une indication très claire de ce qui se passe. Le rune membre de cobra s'attend à ce que son rappel renvoie une erreur (ou zéro en cas de succès).

Ici, vous renvoyez un résultat, qui n'est pas une erreur mais le type spécifique renvoyé par la requête SQL. Voici à quoi devrait ressembler votre fonction.

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
}

Si vous avez besoin du résultat de la commande db.exec (ce qui ne semble pas être le cas), vous devez effectuer tous les traitements requis dans le rappel cobra, car il n'est pas conçu pour renvoyer des valeurs au thread principal.

Gestion des erreurs

Quelques mauvaises pratiques que j'ai remarquées dans mon code concernant la gestion des erreurs :

  • Si une fonction go renvoie une erreur, ne paniquez pas et ne terminez pas le programme si quelque chose d'inattendu se produit (comme vous l'avez fait avec log.fatal). Au lieu de cela, utilisez ce retour d'erreur pour propager l'erreur au thread principal et laissez-le décider quoi faire.

  • D'un autre côté, si quelque chose ne va pas, ne renvoyez pas de résultats. En cas d'échec, votre fonction getconnection devrait pouvoir renvoyer une erreur : func getconnection() (*sql.db, error). Vous devez alors gérer cette erreur dans la fonction getconnection 函数应该能够返回错误:func getconnection() (*sql.db, error)。然后,您应该在 rune au lieu de simplement la consigner et la gérer normalement.

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