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

5 回复

关于 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
}

关键点是:

  1. 不要使用 fmt.Sprintf 来构建 SQL 语句
  2. 确保 SQL 语句中的参数占位符格式正确
  3. 参数传递要与占位符匹配

修正后,sql: expected 0 arguments 错误应该会消失,因为现在参数传递方式是正确的。

回到顶部