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

WBOY
发布: 2024-02-08 21:39:23
转载
681 人浏览过

如何解决 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 character\n"
登录后复制

解决方法

直接的问题是您正在使用 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"
登录后复制

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

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

以上是如何解决 Golang 中的错误'ORA-00911:无效字符”?的详细内容。更多信息请关注PHP中文网其他相关文章!

相关标签:
来源:stackoverflow.com
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!