在Golang中动态传递SQL参数



我在数据库表中有一个SELECT查询,如下所示为常量。

select * from dbo.student where dob > @date_of_birth and grade = @grade

我将像下面这样从Kafka消息中获取参数和值,我需要用Golang中的Kafka消息值替换这两个参数。对于数据库表中的每个查询,此表和参数可能不同。所以我需要写一个泛型函数来替换参数,如果任何表或任何数字参数传递。

{
"message": [{
"sql_table": "student",
"input_params": [{
"key": "@date_of_birth",
"value": "2012-03-03"
},
{
"key": "@grade",
"value": "5"
}
]
}
]
}

首先,您需要确保您正在使用的db驱动程序确实支持命名参数(例如go-mssqldb),然后您可以执行以下操作:

将kafka消息解组到一个struct中,循环遍历输入参数来创建一个args列表(类型为[]any),在循环体中使用每个输入参数对象来创建一个sql.NamedArg值,然后使用...来"解包";当调用db.Query()方法时的参数

type KafkaMessage struct {
Message []Message `json:"message"`
}
type Message struct {
SQLTable    string        `json:"sql_table"`
InputParams []InputParams `json:"input_params"`
}
type InputParams struct {
Key   string `json:"key"`
Value any    `json:"value"`
}
func ExecQuery(db *sql.DB, m Message) (*sql.Rows, error) {
queryString := "..." // based on m.SQLTable get the correct SQL query string
args := make([]any, len(m.InputParams))
for i, pp := range m.InputParams {
name := pp.Key[1:] // drop the leading "@"
args[i] = sql.Named(name, pp.Value)
}
return db.Query(queryString, args...)
}
// ...
var km KafkaMessage // unmarshal the kafka message into km
rows, err := ExecQuery(db, km.Message[0])
if err != nil {
panic(err)
}
defer rows.Close()
for rows.Next() {
// ...
}

最新更新