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

huangapple go评论87阅读模式
英文:

Query with parameter with golang and sqlserver driver

问题

我正在尝试从我的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})
}

我正在使用这个包作为SQL Server驱动程序,它有一个示例应该可以正常工作: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
    }
}
英文:

I'm trying to get a specific item by ID from my sql server database. Here's my code :

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

I'm using this package for the sqlserver driver and it has this example who should work fine : db.Query("SELECT * FROM t WHERE a = ?3, b = ?2, c = ?1", "x", "y", "z")

But everytime I try to call this function it fails and returns :
2017/09/01 16:31:01 mssql: Incorrect syntax near '?'.

So I don't really understand why my query doesn't work..

EDIT

I tried another way, I removed the part where I prepare the query before executing and now it doesn't crash my server, I have a response but the problem is still the same :

var row = db.QueryRow(findArticlesQry, id).Scan(&article.Title, &article.Description, &article.Body, &article.Id)

And the response :

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

答案1

得分: 5

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

> sqlserver驱动程序使用正常的MS SQL Server语法,并且期望查询中的参数形式为@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"
)
英文:

Per your comment, you are using the sqlserver driver, not the mssql driver, so you are using the wrong parameter format. Per the documentation:

> The sqlserver driver uses normal MS SQL Server syntax and expects
> parameters in the sql query to be in the form of either @Name or @p1
> to @pN (ordinal position).
>
> db.QueryContext(ctx, "select * from t where ID = @ID;", sql.Named("ID", 6))

You should therefore change your query to be:

var(
    allArticlesQry string = "SELECT * FROM Articles"
    findArticlesQry string = "SELECT * FROM Articles WHERE Id = @p1"
)

答案2

得分: 2

似乎是占位符的问题。为什么不尝试将占位符简化为 "?",因为您没有改变顺序或重复使用它们。所以请尝试这样写:

"SELECT * FROM Articles WHERE Id = ?"
英文:

It seems to be a problem with the placeholders. Why not try just ? for your placeholders as you're not shifting the order or repeating them. So try this:

"SELECT * FROM Articles WHERE Id = ?"

答案3

得分: 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 语法,不允许使用问号。

英文:

db.Query("SELECT * FROM t WHERE a = ?3, b = ?2, c = ?1", "x", "y", "z"), the question mark here works as placeholder, which later will be replaced with the value of 'x', 'y' and 'z' according to its order in the code during runtime.

But this:

SELECT * FROM Articles WHERE Id = ?1 is not a validate SQL statement, correct is to remove the question mark, or you could give a specific value to @Id, like:

SELECT * FROM Articles WHERE Id = @Id

In a short word, db.Query() could build your query using placeholder, but your findArticlesQry variable is storing plain SQL statement, that should follow the basic SQL grammar, ? is not allowed.

huangapple
  • 本文由 发表于 2017年9月1日 22:44:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/46002760.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定