Heim  >  Artikel  >  Backend-Entwicklung  >  Wie behebe ich den Fehler „ORA-00911: ungültiges Zeichen“ in Golang?

Wie behebe ich den Fehler „ORA-00911: ungültiges Zeichen“ in Golang?

WBOY
WBOYnach vorne
2024-02-08 21:39:23702Durchsuche

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

Während des Entwicklungsprozesses von Golang stoßen wir manchmal auf Fehler wie „ORA-00911: ungültiges Zeichen“. Dieser Fehler wird normalerweise durch die Verwendung ungültiger Zeichen in der SQL-Anweisung verursacht. Um dieses Problem zu lösen, können wir einige einfache Methoden anwenden. Bevor wir die SQL-Anweisung ausführen, sollten wir zunächst sorgfältig prüfen, ob die Anweisung Sonderzeichen oder ungültige Zeichen enthält. Zweitens können wir versuchen, Felder oder Werte, die Sonderzeichen enthalten, in Anführungszeichen zu setzen, um Fehler zu vermeiden. Darüber hinaus können Sie Escape-Zeichen auch zur Verarbeitung von Sonderzeichen verwenden, um sicherzustellen, dass diese in SQL-Anweisungen korrekt erkannt und verarbeitet werden. Mit diesen Methoden können wir das Problem „ORA-00911: ungültiges Zeichen“ in Golang effektiv lösen und sicherstellen, dass unser Programm normal ausgeführt werden kann.

Frageninhalt

Beim Aufruf der folgenden Funktion ist der Fehler „ORA-00911: ungültiges Zeichen“ aufgetreten. Wenn ich eine SQL-Abfrage mit fest codierten Werten verwende (derzeit ist sie im folgenden Codeausschnitt auskommentiert), kann ich die Datenbankeinträge problemlos in einer JSON-Antwort in Postman abrufen. Es sieht also so aus, als ob ich meine Argumentation falsch mache. Zu Ihrer Information: Ich verwende das Paket „github.com/sijms/go-ora/v2“, um eine Verbindung zur Oracle-Datenbank herzustellen. Außerdem befindet sich die Struktur „DashboardRecordsRequest“ im Datenmodellpaket, ich habe sie jedoch als Referenz in den folgenden Ausschnitt eingefügt. Bitte beachten Sie, dass wir beim POC gespeicherte Prozeduren verwenden, um mit Oracle zu interagieren.

Postman-Anfrage laden:

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

Ausführungscode:

<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>

Tabellenstruktur anfordern:

<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>

Fehler:

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"

Workaround

Das unmittelbare Problem besteht darin, dass Sie ein Paket im JDBC-Stil ? 绑定占位符,而不是预期的 :var 形式。从 go-ora verwenden. In der Dokumentation sagen Sie, dass Sie Folgendes verwenden:

Ihr stmt sollte also sein:

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

Da Sie jedoch nichts anderes als eine Variable binden können, können Sie sortorder überhaupt nicht als Variable verwenden, wenn Sie es einfach entfernen und Folgendes tun:

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

Das scheint zu funktionieren, aber selbst das macht nicht ganz das, was Sie wollen, weil die Sortierung nach dem wörtlichen Spaltennamen und nicht nach seinem Wert erfolgt, sodass es wie folgt funktioniert: ORDER BY 'requestnumber' 的等效项运行,而不是 ORDER BY requestnumber Und das Sortieren nach dieser konstanten Zeichenfolge bringt nichts.

Sie müssen die Bestellkriterien in die Abrechnung einbetten:

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

dba8093152e673feb7aba1828c43532094fiddle verwendet einen dynamischen PL/SQL-Cursor als vereinfachtes Äquivalent und zeigt drei Versionen an – eine falsch, eine nicht wie erwartet geordnet und schließlich ordnungsgemäß geordnet.

Aber Sie müssen diese Eingaben auch bereinigen, um eine erneute SQL-Injection zu verhindern.

Das obige ist der detaillierte Inhalt vonWie behebe ich den Fehler „ORA-00911: ungültiges Zeichen“ in Golang?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen