Maison  >  Article  >  développement back-end  >  Comment résoudre l'erreur « ORA-00911 : caractère invalide » dans Golang ?

Comment résoudre l'erreur « ORA-00911 : caractère invalide » dans Golang ?

WBOY
WBOYavant
2024-02-08 21:39:23702parcourir

如何解决 Golang 中的错误“ORA-00911:无效字符”?

Pendant le processus de développement de Golang, nous rencontrons parfois des erreurs telles que "ORA-00911 : caractère invalide". Cette erreur est généralement provoquée par l'utilisation de caractères non valides dans l'instruction SQL. Pour résoudre ce problème, nous pouvons utiliser quelques méthodes simples. Tout d'abord, avant d'exécuter l'instruction SQL, nous devons soigneusement vérifier s'il y a des caractères spéciaux ou des caractères invalides dans l'instruction. Deuxièmement, nous pouvons essayer d'utiliser des guillemets pour délimiter des champs ou des valeurs contenant des caractères spéciaux afin d'éviter les erreurs. De plus, vous pouvez également utiliser des caractères d'échappement pour traiter les caractères spéciaux afin de garantir qu'ils sont correctement reconnus et traités dans les instructions SQL. Grâce à ces méthodes, nous pouvons résoudre efficacement le problème « ORA-00911 : caractère invalide » dans Golang et garantir que notre programme peut fonctionner normalement.

Contenu de la question

J'ai rencontré l'erreur "ORA-00911 : caractère invalide" lors de l'appel de la fonction suivante. Si j'utilise une requête SQL avec des valeurs codées en dur (pour l'instant, elle est commentée dans l'extrait ci-dessous), je peux alors obtenir les enregistrements de la base de données dans une réponse JSON dans Postman sans aucun problème. Il semble donc que je me trompe dans mon argumentation. Pour information, j'utilise le package "github.com/sijms/go-ora/v2" pour me connecter à Oracle DB. De plus, la structure « DashboardRecordsRequest » se trouve dans le package de modèle de données, mais je l'ai collée dans l'extrait ci-dessous pour référence. Veuillez noter que lorsque je ferai le POC, nous utiliserons des procédures stockées pour interagir avec Oracle.

Chargement des demandes du facteur :

<code>{
    "username": "UserABC",
    "startindex": 0,
    "pagesize": 10,
    "sortby": "requestnumber",
    "sortorder": "DESC"
}
</code>

Code d'exécution :

<code>type DashboardRecordsRequest struct {
    Username                string `json:"username"`    
    StartIndex              int    `json:"startindex"`
    PageSize                int    `json:"pagesize"`
    SortBy                  string `json:"sortby"`
    SortOrder               string `json:"sortorder"`
}

func GetDashboardActiveRequestRecords(request datamodel.DashboardRecordsRequest) ([]datamodel.ActiveRequestRecord, error) {
    sortby := request.SortBy
    sortorder := request.SortOrder
    startindex := request.StartIndex
    pagesize := request.PageSize
    activerecords := []datamodel.ActiveRequestRecord{}

    slog.Info("Verify values", slog.String("sortby", sortby), slog.String("sortorder", sortorder), slog.Int("startindex", startindex), slog.Int("pagesize", pagesize))

    dbconn, err := getDBConnection()
    if err != nil {
        logger.Error("Could not connect to database")
        return activerecords, err
    }
    stmt, err := dbconn.Prepare("SELECT requestnumber, requeststatus, NVL(requestor, 'N/A'), NVL(pendingwith, 'N/A'), NVL(processtype, 'N/A'), actiondate FROM requests WHERE requeststatus = 'PENDINGAPPROVAL' ORDER BY ? ? OFFSET ? ROWS FETCH NEXT ? ROWS ONLY")
    /*stmt, err := dbconn.Prepare("SELECT requestnumber, requeststatus, NVL(requestor, 'N/A'), NVL(pendingwith, 'N/A'), NVL(processtype, 'N/A'), actiondate FROM requests WHERE requeststatus = 'PENDINGAPPROVAL' ORDER BY requestnumber DESC OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY")*/
    if err != nil {
        logger.Error("Error while building prepared statement for retrieving dashboard active records", slog.String("Error", err.Error()))
        return activerecords, err
    }
    rows, err := stmt.Query(sortby, sortorder, startindex, pagesize)
    //rows, err := stmt.Query()
    if err != nil {
        logger.Error("Error while executing prepared statement for retrieving dashboard active records", slog.String("Error", err.Error()))
        return activerecords, err
    }
    defer rows.Close()

    for rows.Next() {
        var rec datamodel.ActiveRequestRecord
        err = rows.Scan(&rec.RequestNumber, &rec.RequestStatus, &rec.RequestorName, &rec.PendingWith, &rec.ProcessType, &rec.LastActionDate)
        if err != nil {
            logger.Error("Error while processing database resultset for dashboard active records", slog.String("Error", err.Error()))
            return activerecords, err
        }
        activerecords = append(activerecords, rec)
    }
    return activerecords, err
}
</code>

Demander la structure du tableau :

<code>CREATE TABLE "REQUESTS" (
    "REQUESTNUMBER"          VARCHAR2(64 CHAR) NOT NULL ENABLE,
    "REQUESTSTATUS"          VARCHAR2(128 CHAR) NOT NULL ENABLE,
    "SUBMISSIONDATE"         TIMESTAMP(6),
    "PROCESSTYPE"            VARCHAR2(256 CHAR),
    "SUBMITTER"              VARCHAR2(256 CHAR) NOT NULL ENABLE,
    "REQUESTOR"              VARCHAR2(512 CHAR),
    "PENDINGWITH"            VARCHAR2(512 CHAR),
    "ACTIONDATE"             TIMESTAMP(6),
    "RESUBMISSIONDATE"       TIMESTAMP(6),
    PRIMARY KEY ( "REQUESTNUMBER" ),
    FOREIGN KEY ( "SUBMITTER" )
        REFERENCES "SUBMITTERS" ( "USERNAME" )
)
</code>

Erreur :

time=2023-10-04T06:43:06.304Z level=INFO source=C:/code/tutorials/myapp/internal/storage/dashboard.go:19 msg="Verify values" sortby=requestnumber sortorder=DESC startindex=0 pagesize=10
time=2023-10-04T06:43:06.603Z level=ERROR source=C:/code/tutorials/myapp/internal/storage/dashboard.go:34 msg="Error while executing prepared statement for retrieving dashboard active records" Error="ORA-00911: invalid character\n"

Solution de contournement

Le problème immédiat est que vous utilisez un package ? 绑定占位符,而不是预期的 :var 形式。从 go-ora de style JDBC. Dans la documentation , vous dites que vous utilisez : .

Donc votre stmt devrait être :

SELECT requestnumber, requeststatus, NVL(requestor, 'N/A'), NVL(pendingwith, 'N/A'), NVL(processtype, 'N/A'), actiondate
FROM requests WHERE requeststatus = 'PENDINGAPPROVAL'
ORDER BY :sortby :sortorder OFFSET :startindex ROWS FETCH NEXT :pagesize ROWS ONLY

Mais vous ne pouvez rien lier d'autre qu'une variable, donc cela ne vous permet pas du tout d'avoir sortorder comme variable, si vous le supprimez simplement et faites :

ORDER BY :sortby OFFSET :startindex ROWS FETCH NEXT :pagesize ROWS ONLY

Cela semble fonctionner, mais même cela ne fait pas tout à fait ce que vous voulez car le tri triera par le nom littéral de la colonne plutôt que par sa valeur, donc cela fonctionnera comme ORDER BY 'requestnumber' 的等效项运行,而不是 ORDER BY requestnumber. Et trier selon cette chaîne constante ne servira à rien.

Vous devez intégrer les critères de commande dans la déclaration :

"... ORDER BY " + sortby + " " + sortorder + " OFFSET :startindex ROWS FETCH NEXT :pagesize ROWS ONLY"

dba8093152e673feb7aba1828c43532094fiddle utilise un curseur dynamique PL/SQL comme équivalent simplifié, affichant trois versions - une fausse, une non ordonnée comme prévu et finalement bien ordonnée.

Mais vous devez également nettoyer ces entrées pour empêcher à nouveau l'injection SQL.

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