在golang中对SQL子查询进行参数化处理

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

parameterizing SQL subquery in golang

问题

请考虑以下问题。

我需要在golang中对SQL(子)查询进行参数化。请考虑下面的伪代码或者在https://go.dev/play/p/F-jZGEiDnsd中查看。

hayStack的详细信息以字符串切片lookIn的形式传递给我,可能会有所变化。我需要在所有这些hayStacks中搜索%eedl%(needle)。

注释中的代码是我目前的处理方式 - 我只对我要查找的needle进行参数化。

如何对hayStacks进行参数化?

package main

import "fmt"

func main() {
	fmt.Println("Hello, 世界")
	lookIn := []string{"hayStack.1", "hayStack.2", "hayStack.3", "hayStack.4", "hayStack.5"}
	needle := "eedl"
	needle = "%" + needle + "%"

	for i := range lookIn {
		fmt.Println("lookIn", lookIn[i])
	}
	fmt.Println("needle", needle)

	/* this is how I currently do 
		txt := `select needle,tagTitle,Epoch from ( select needle,tagTitle,Epoch where hayStackName = "hayStack.1" or hayStackName = "hayStack.2" or hayStackName = "hayStack.3" or hayStackName = "hayStack.3" or hayStackName = "hayStack.4" or hayStackName = "hayStack.5" )  where tagTitle like ? order by tagTitle COLLATE NOCASE ASC ;`
		rows, err := sqliteDbPtr.Query(txt, needle)

		if err != nil {
			if err != sql.ErrNoRows {
				checkErr(err)
				panic(err)
			}
			return
		}
		defer rows.Close()
	*/

}

非常感谢您的任何建议。

英文:

Please consider this question.

I need to parameterize a SQL (sub) query in golang. Please consider the pseudo-code below or at https://go.dev/play/p/F-jZGEiDnsd

The hayStack details come to me in an string slice lookIn and can vary. I need to search for %eedl% (needle) in all these haystacks.

The code in the comment is how I currently handle it - I only parameterize the needle I am looking for.

How do I parameterize the hayStacks as well?

package main

import "fmt"

func main() {
	fmt.Println("Hello, 世界")
	lookIn := []string{"hayStack.1", "hayStack.2", "hayStack.3", "hayStack.4", "hayStack.5"}
	needle := "eedl"
	needle = "%" + needle + "%"

	for i := range lookIn {
		fmt.Println("lookIn", lookIn[i])
	}
	fmt.Println("needle", needle)

	/* this is how I currently do 
		txt := `select needle,tagTitle,Epoch from ( select needle,tagTitle,Epoch where hayStackName = "hayStack.1" or hayStackName = "hayStack.2" or hayStackName = "hayStack.3" or hayStackName = "hayStack.3" or hayStackName = "hayStack.4" or hayStackName = "hayStack.5" )  where tagTitle like ? order by tagTitle COLLATE NOCASE ASC ;`
		rows, err := sqliteDbPtr.Query(txt, needle)

		if err != nil {
			if err != sql.ErrNoRows {
				checkErr(err)
				panic(err)
			}
			return
		}
		defer rows.Close()
	*/

}

Any input will be much appreciated.

答案1

得分: 1

只使用标准库,你可以将 haystack 参数和 needle 参数收集到一个单独的切片中,然后将其传递给 Query 方法。

对于 SQL 本身,你可以使用 IN 运算符,并根据 haystack 的数量生成 ? 的列表作为其右操作数。

args := make([]interface{}, len(lookIn)+1) // 所有参数的切片
inRHS := "" // IN 运算符右操作数的字符串,形式为 ?,...
for i := range lookIn {
	args[i] = lookIn[i]
	inRHS += "?,"
}
args[len(args)-1] = needle   // 添加最后一个参数
inRHS = inRHS[:len(inRHS)-1] // 移除最后一个逗号
query := `SELECT needle,tagTitle,Epoch
FROM some_table
WHERE hayStackName IN (` + inRHS + `)
AND tagTitle LIKE ?
ORDER BY tagTitle COLLATE NOCASE ASC`

rows, err := sqliteDbPtr.Query(query, args...)
if err != nil {
    // 处理错误
}
defer rows.Close()

for rows.Next() {
	//
}
if err := rows.Err(); err != nil {
	//
}

注意,我已经删除了子查询,并添加了 FROM some_table 子句,这是你的问题中缺少的部分。

英文:

Using just the standard library you can collect the haystack arguments and the needle argument into a single slice and then pass that to the Query method.

For the SQL itself you can use the IN operator and generate its right hand side operand as a list of ? based on the number of haystacks.

args := make([]interface{}, len(lookIn)+1) // slice of all args
inRHS := "" // string of ?,... for the IN operator's right hand side
for i := range lookIn {
	args[i] = lookIn[i]
	inRHS += "?,"
}
args[len(args)-1] = needle   // add the last arg
inRHS = inRHS[:len(inRHS)-1] // remove last ","
query := `SELECT needle,tagTitle,Epoch
FROM some_table
WHERE hayStackName IN (` + inRHS + `)
AND tagTitle LIKE ?
ORDER BY tagTitle COLLATE NOCASE ASC`

rows, err := sqliteDbPtr.Query(query, args...)
if err != nil {
    // handle error
}
defer rows.Close()

for rows.Next() {
	//
}
if err := rows.Err(); err != nil {
	//
}

NOTE that I've removed the subquery and added the FROM some_table clause which your question was missing.

huangapple
  • 本文由 发表于 2022年2月10日 12:30:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/71059831.html
匿名

发表评论

匿名网友

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

确定