Golang创建新行时遇到的错误
Golang创建新行时遇到的错误
我正在尝试使用 denisenkom go-mssqldb 包和驱动向 MS SQL 插入新行。
tsql := fmt.Sprintf("INSERT INTO Uploads (Fname, Fsize, Ftype) VALUES (@Fname, @Fsize, @Ftype );")
fmt.Printf("tsql = %s\n", tsql)
//Execute non-query with named parameters
res, err := db.ExecContext(
ctx,
tsql,
sql.Named("Fname", fname),
sql.Named("Fsize", fsize),
sql.Named("Ftype", ftype))
if err != nil {
log.Fatal(" AddRow_v1() -> Error creating new row: " + err.Error())
return -1, err
}
我遇到了不必要的 fmt.Sprintf 使用。
同时,我遇到了一个终端错误:sql: expected 0 arguments。
更多关于Golang创建新行时遇到的错误的实战教程也可以访问 https://www.itying.com/category-94-b0.html
关于 error sql: expected 0 arguments 这个错误,你使用的是哪个 SQL 库?它支持命名参数吗?
更多关于Golang创建新行时遇到的错误的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
我快速浏览了 mssql 包 - github.com/denisenkom/go-mssqldb - pkg.go.dev,但没能发现这个问题,也许其他人可以在这里提供帮助?
我看到这个错误是因为你在使用
Sprintf时没有使用任何格式化占位符或变量。相反,直接将原始字符串赋值给tsql即可:
tsql := "INSERT INTO Uploads (Fname, Fsize, Ftype) VALUES (@Fname, @Fsize, @Ftype );"
我正在使用 github.com/denisenkom/go-mssqldb 来连接 Microsoft SQL Server 2014 - 12.0.2269.0 (X64) Jun 10 2015 03:35:45 Copyright (c) Microsoft Corporation Express Edition (64-bit) on Windows NT 6.3 <X64> (Build 19042: )
哪个 SQL 库支持命名参数?
这个错误是因为你混合了两种不同的参数传递方式。go-mssqldb 驱动支持命名参数,但你需要使用正确的语法。问题在于你的 SQL 语句使用了 @ 参数,但 ExecContext 调用时应该直接使用参数化查询,而不是字符串格式化。
以下是修正后的代码:
tsql := "INSERT INTO Uploads (Fname, Fsize, Ftype) VALUES (@p1, @p2, @p3);"
fmt.Printf("tsql = %s\n", tsql)
// 使用正确的参数占位符
res, err := db.ExecContext(
ctx,
tsql,
sql.Named("p1", fname),
sql.Named("p2", fsize),
sql.Named("p3", ftype))
if err != nil {
log.Fatal("AddRow_v1() -> Error creating new row: " + err.Error())
return -1, err
}
或者使用更简洁的方式,直接传递参数而不使用 sql.Named:
tsql := "INSERT INTO Uploads (Fname, Fsize, Ftype) VALUES (@p1, @p2, @p3);"
fmt.Printf("tsql = %s\n", tsql)
// 直接传递参数值
res, err := db.ExecContext(ctx, tsql, fname, fsize, ftype)
if err != nil {
log.Fatal("AddRow_v1() -> Error creating new row: " + err.Error())
return -1, err
}
对于 go-mssqldb 驱动,参数占位符应该是 @p1, @p2, @p3 等形式。驱动会自动将位置参数映射到对应的占位符。
如果你想要使用命名的参数映射,可以这样写:
tsql := "INSERT INTO Uploads (Fname, Fsize, Ftype) VALUES (@Fname, @Fsize, @Ftype);"
res, err := db.ExecContext(
ctx,
tsql,
sql.Named("Fname", fname),
sql.Named("Fsize", fsize),
sql.Named("Ftype", ftype))
if err != nil {
log.Fatal("AddRow_v1() -> Error creating new row: " + err.Error())
return -1, err
}
关键点是:
- 不要使用
fmt.Sprintf来构建 SQL 语句 - 确保 SQL 语句中的参数占位符格式正确
- 参数传递要与占位符匹配
修正后,sql: expected 0 arguments 错误应该会消失,因为现在参数传递方式是正确的。

