卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章34393本站已运行393

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

如何解决 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 交互。

邮差请求负载:

{
    "username": "UserABC",
    "startindex": 0,
    "pagesize": 10,
    "sortby": "requestnumber",
    "sortorder": "DESC"
}

执行代码:

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
}

请求表结构:

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

错误:

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

解决方法

直接的问题是您正在使用 JDBC 样式的 ? 绑定占位符,而不是预期的 :var 形式。从 go-ora 包的文档中,您说您正在使用:< /p>

所以你的 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"

dbfiddle 使用 PL/SQL 动态游标作为简化的等效项,显示三个版本 - 一个错误,一个没有按预期订购,最后订购正常。

但是您还需要清理这些输入以再次防止 SQL 注入。

卓越飞翔博客
上一篇: 转换朴素递归硬币问题时记忆错误
下一篇: 返回列表
留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏