2015-08-18 53 views
1

我嘗試做一個查詢,像這樣佔位符的Postgres的查詢generate_series返回未知

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

什麼類型max_id和min_id? – kostya

+0

它們是整數,它們是有效的 – ekiyanov

+0

在Go中有許多整數類型:int,uint,int64等。我瘋狂的猜測是postgresql驅動程序不支持所有這些類型。嘗試使用int64。 – kostya

回答

6

嘗試分開破壞你的查詢。你會看到的第一部分工作正常:

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)

+0

它的工作原理。謝謝。 – ekiyanov

+0

@ekiyanov沒問題! – steevee