出于某种原因,我使用 pgx 在 go 中构建的 prepareStatement 没有返回任何结果/行(参见场景 1)。在场景 2 中,如果我使用 Sprintf 和 $ 构建相同的查询,也不会返回结果。
但是,如场景 3 所示,如果我使用带有 %s 占位符的 Sprintf 构建查询并执行它,它将返回结果/行。
我想使用场景 1 的“逻辑”构建/执行查询(使用准备好的语句而不是使用 Sprintf)。有任何想法吗?
我直接在数据库上测试了查询(使用 pgadmin),它有数据/结果。
假设: 我怀疑它可能与以下内容有关:
- 在 WHERE 条件下:uuid 数据类型或在 IN 条件下带有字符串
- 返回一个uuid和一个jsonb的查询结果
详细信息: 数据库是 postgres,表 t 具有以下字段类型:
- t.str1 和 t.properties 是字符串
- t.my_uuid 是 uuid.UUID ( https://github.com/satori/go.uuid )
- tC 是 jsonb
- 我正在使用的 pgx 版本是:github.com/jackc/pgx v3.6.2+incompatible
情景 1
func prepareQuery(cp *pgx.ConnPool) (string, error) {
prep := `SELECT DISTINCT
A,B,C
FROM table t
WHERE t.str1 = $1
AND t.properties IN ($2)
AND t.my_uuid = $3`
_, err := cp.Prepare("queryPrep", prep)
if err != nil {
return "some error", err
}
return prep, nil
}
func x() {
//...
q, err := prepareQuery(cPool)
if err != nil {
return fmt.Errorf("failed to prepare query %s: %w", q, err)
}
rows, err := cPool.Query("queryPrep", "DumyStr", "'prop1','prop2'", myUUID) //myUUID is a valid satori uuid
if err != nil {
//return error...
}
for rows.Next() { // zero rows
//Scan...
}
//...
}
情景 2
func makeQueryStr()string {
return fmt.Sprintf(`SELECT DISTINCT
A,B,C
FROM table t
WHERE t.str1 = $1
AND t.properties IN ($2)
AND t.my_uuid = $3`)
}
func x() {
//...
myQuery := makeQueryStr()
rows, err := cPool.Query(myQuery, "DumyStr", "'prop1','prop2'", myUUID) //myUUID is a valid satori uuid
if err != nil {
//return error...
}
for rows.Next() { // zero rows
//Scan...
}
//...
}
情景 3
func makeQueryStr(par1 string, par2 string, par3 uuid.UUID)string {
return fmt.Sprintf(`SELECT DISTINCT
A,B,C
FROM table t
WHERE t.str1 = '%s'
AND t.properties IN (%s)
AND t.my_uuid = '%s'`, par1, par2, par3)
}
func x() {
//...
myQuery := makeQueryStr("DumyStr", "'prop1','prop2'", myUUID) //myUUID is a valid satori uuid
rows, err := cPool.Query(myQuery)
if err != nil {
//return error...
}
for rows.Next() { // 10 rows
//Scan...
}
//...
}