首頁  >  文章  >  後端開發  >  如何解決 Golang 中的錯誤“ORA-00911:無效字元”?

如何解決 Golang 中的錯誤“ORA-00911:無效字元”?

WBOY
WBOY轉載
2024-02-08 21:39:23702瀏覽

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

在Golang開發過程中,我們有時會遇到"ORA-00911: 無效字元"這樣的錯誤。這種錯誤通常是由於在SQL語句中使用了無效的字元而引起的。要解決這個問題,我們可以採取一些簡單的方法。首先,在執行SQL語句之前,我們應該仔細檢查語句中是否有特殊字元或無效字元。其次,我們可以嘗試使用引號將包含特殊字元的欄位或值括起來,以避免出現錯誤。另外,也可以使用轉義字符來處理特殊字符,確保其在SQL語句中被正確地識別和處理。透過這些方法,我們可以有效地解決Golang中出現"ORA-00911: 無效字元"的問題,確保我們的程式能夠正常運作。

問題內容

我在呼叫以下函數時遇到錯誤「ORA-00911:無效字元」。如果我使用帶有硬編碼值的 SQL 查詢(截至目前,它已在下面的程式碼片段中註解掉),那麼我可以在郵遞員中以 JSON 回應取得資料庫記錄,沒有任何問題。所以,看起來我的論點做錯了。僅供參考,我正在使用“github.com/sijms/go-ora/v2”套件連接到 oracle db。 另外,「DashboardRecordsRequest」結構位於資料模型包中,但我已將其貼到下面的程式碼片段中以供參考。 請注意,當我進行 POC 時,我們將使用預存程序與 Oracle 互動。

郵差請求負載:

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

執行程式碼:

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

請求表結構:

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

錯誤:

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"

解決方法

直接的問題是您正在使用JDBC 樣式的? 綁定佔位符,而不是預期的:var#形式。從 go-ora 套件的文檔中,您說您正在使用:

所以你的 stmt 應該是:

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

但是除了變數之外你不能綁定任何東西,所以它根本不允許你將 sortorder 作為變量,如果你只是刪除它並執行以下操作:

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

這似乎可以工作,但即使這樣也不能完全達到您想要的效果,因為排序將按文字列名稱而不是它的值進行排序;因此它將作為ORDER BY 'requestnumber' 的等效項運行,而不是ORDER BY requestnumber。並且按該常數字串排序不會實現任何目標。

您需要在語句中嵌入訂購標準:

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

dba8093152e673feb7aba1828c43532094fiddle 使用 PL/SQL 動態遊標作為簡化的等效項,顯示三個版本 - 一個錯誤,一個沒有按預期訂購,最後訂購正常。

但是您還需要清理這些輸入以再次防止 SQL 注入。

以上是如何解決 Golang 中的錯誤“ORA-00911:無效字元”?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除