2

このようなプレースホルダーを使用してクエリを作成しようとしています

database.Query("select login,displayname from (select distinct $1+trunc(random()*$2)::integer as id from generate_series($3,$4) g ) r join users using(id) limit 10",min_id,max_id-min_id,min_id,max_id)

それは私にエラーをスローします:

pq: function generate_series(unknown, unknown) is not unique

次に、クエリを文字列としてフォーマットする解決策を見つけます

query:=fmt.Sprintf("select login,displayname from (select distinct %v+trunc(random()*%v)::integer as id from generate_series(%v,%v) g ) r join users using(id) limit 10",min_id,max_id-min_id,min_id,max_id)

そしてそれは動作します。

うまく機能させたいのですが、なぜうまくいかないのかわかりません。

更新しました:

var min_id int64
var max_id int64
err:=_database.QueryRow("select min(id),max(id) from users").Scan(&min_id, &max_id)
if err!=nil { 
    log.Panicf("Failed to get min and max %v",err.Error())
    return
}

var rows *sql.Rows

query:=fmt.Sprintf("select login,displayname from (select distinct %v+trunc(random()*%v)::integer as id from generate_series(%v,%v) g ) r join users using(id) limit 10",min_id,max_id-min_id,min_id,max_id)
log.Printf(query)
rows,err=_database.Query("select login,displayname from (select distinct $1+trunc(random()*$2)::integer as id from generate_series($3,$4) g ) r join users using(id) limit 10",min_id,max_id-min_id,min_id,max_id)
if err!=nil {
    log.Panicf("failed to get random entries: %v",err)
}
4

1 に答える 1

8

クエリを分解してみてください。最初の部分が正常に動作することがわかります。

db.QueryRow("SELECT $1+trunc(random()*$2) as test", 10, 5)

これはおそらく、 と が数学演算子で使用されているため$1($2および/またはtrunc()random()両方が数値を返すため)、postgres がデータ型を推測できるため機能します。

そのため、generate_series()適切に決定されていないパラメータのようです。Postgresは、パラメーターに基づいてデータ型を推測できます。

if err := db.QueryRow("SELECT trunc($1,2) as test", 1.4343).Scan(&output); err != nil {panic(err)}
// output = 1.43

ただし、それが多相関数の場合、あいまいさが発生する可能性があり、失敗します。

if err := db.QueryRow("SELECT trunc($1) as test", 1.4343).Scan(&output); err != nil {panic(err)}
// panic: pq: function trunc(unknown) is not unique

あいまいさを避けるために、次のように、準備されたステートメントでパラメーターを明示的にキャストします。generate_series($3::int,$4::int)

于 2015-08-18T12:34:09.540 に答える