使用 Golang 和 SQL Server 驱动程序进行带参数的查询

3
我正在尝试从我的 SQL Server 数据库中按 ID 获取特定项。以下是我的代码:
var(
    allArticlesQry string = "SELECT * FROM Articles"
    findArticlesQry string = "SELECT * FROM Articles WHERE Id = ?1"
)

func FindArticle(w http.ResponseWriter, r *http.Request){
    vars := mux.Vars(r)
    var id = vars["id"]
    var article Article

    db := connect()
    defer db.Close()

    stmt, err := db.Prepare(findArticlesQry)    
    if err != nil{
        log.Fatal(err)
    }
    defer stmt.Close()

    err = stmt.QueryRow(id).Scan(&article.Title, &article.Description, &article.Body, &article.Id)
    if err != nil{
        log.Fatal(err)
    }

    w.Header().Set("Content-Type", "application/json; charset=UTF-8")
    w.WriteHeader(http.StatusOK)
    json.NewEncoder(w).Encode(u.HttpResp{Status: 200, Body: article})
}

我正在使用这个用于sqlserver驱动程序的包,并且它有一个可以正常工作的示例: db.Query("SELECT * FROM t WHERE a = ?3, b = ?2, c = ?1", "x", "y", "z")。但是每次我尝试调用这个函数时,它会失败并返回:2017/09/01 16:31:01 mssql: Incorrect syntax near '?'.所以我真的不理解为什么我的查询不起作用... 编辑 我尝试了另一种方法,我删除了执行之前准备查询的部分,现在它不会使我的服务器崩溃,我有了一个响应,但问题仍然存在:
var row = db.QueryRow(findArticlesQry, id).Scan(&article.Title, &article.Description, &article.Body, &article.Id)

并且响应:

{
    "status": 200,
    "description": "",
    "body": {
        "Number": 102,
        "State": 1,
        "Class": 15,
        "Message": "Incorrect syntax near '?'.",
        "ServerName": "DESKTOP-DLROBC4\\LOCALHOST",
        "ProcName": "",
        "LineNo": 1
    }
}

你确定你正在使用 mssql 驱动程序而不是 sqlserver 吗?这两个都在同一个包中,但后者期望以不同的格式传递参数。 - stephen.vakil
我正在使用sqlserver驱动程序,但现在不在我的电脑上,所以我会在几个小时后尝试。 - Antoine Thiry
3个回答

5
根据您的评论,您正在使用sqlserver驱动程序而不是mssql驱动程序,因此您使用了错误的参数格式。根据文档:

sqlserver驱动程序使用普通的MS SQL Server语法,期望在sql查询中以@Name@p1@pN(顺序位置)的形式提供参数。

db.QueryContext(ctx, "select * from t where ID = @ID;", sql.Named("ID", 6))

因此,您应该将查询更改为:
var(
    allArticlesQry string = "SELECT * FROM Articles"
    findArticlesQry string = "SELECT * FROM Articles WHERE Id = @p1"
)

谢谢,顺便说一下我从来没有提到过mssql驱动程序,实际上我在我的问题中明确提到了sqlserver驱动程序,但还是谢谢!等我能够访问我的电脑时,我会尝试它。 - Antoine Thiry

2

看起来是占位符的问题。为什么不尝试只使用“?”作为占位符,因为您没有改变顺序或重复使用它们。所以请尝试这个:

"SELECT * FROM Articles WHERE Id = ?"

仍然出现相同的错误,这明显是一个占位符的问题,但我找不到任何文档,因为它是一个社区基础的软件包,可能没有得到积极开发... - Antoine Thiry
看起来驱动程序声称它接受你尝试用于mssql的样式,但不接受sqlserver,也许也要检查一下。 - Kenny Grant
你如何传递占位符的值? - chovy

1

db.Query("SELECT * FROM t WHERE a = ?3, b = ?2, c = ?1", "x", "y", "z"),这里的问号作为占位符,在运行时会根据代码中的顺序替换为'x'、'y'和'z'的值。

但是这个语句:

SELECT * FROM Articles WHERE Id = ?1 不是一个有效的SQL语句,正确的做法是删除问号,或者给@Id赋一个具体的值,例如:

SELECT * FROM Articles WHERE Id = @Id

简而言之,db.Query()可以使用占位符构建查询,但是你的findArticlesQry变量存储的是普通的SQL语句,它应该遵循基本的SQL语法,不允许使用?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接