2016-07-24 7 views
1

私はPostgreSQLデータベースを使用する小さなGoプログラムを持っています。その中には行が返されないクエリがあり、これを処理するために使用しているコードが正しく動作していません。sql.ErrNoRowsを使用したデータベース/ sqlの例がクラッシュして焼く

// Get the karma value for nick from the database. 
func getKarma(nick string, db *sql.DB) string { 
    var karma int 
    err := db.QueryRow("SELECT SUM(delta) FROM karma WHERE nick = $1", nick).Scan(&karma) 
    var karmaStr string 
    switch { 
    case err == sql.ErrNoRows: 
     karmaStr = fmt.Sprintf("%s has no karma.", nick) 
    case err != nil: 
     log.Fatal(err) 
    default: 
     karmaStr = fmt.Sprintf("Karma for %s is %d.", nick, karma) 
    } 
    return karmaStr 
} 

このロジックはGo documentationから直接取得されます。ニックに対応する行がない場合は、次のエラーが発生します。

2016/07/24 19:37:07 sql: Scan error on column index 0: converting driver.Value type <nil> ("<nil>") to a int: invalid syntax 

私は愚かな何かをやっている必要があります - 手がかりは感謝を。

+0

あなたのスイッチで常に 'err'と比較しているのであれば、代わりに' switch err {} 'を使わないのはなぜですか? –

+0

どの "database/sql"ドキュメントを参照していますか?そのコードは、Postgresのマニュアルではほとんどありません。 –

+0

@a_horse_with_no_name:https://golang.org/pkg/database/sql/#DB.Query、QueryRowの例を展開してください。 –

答えて

2

NULLの値がデータベースから戻ってきて、nilに変換されていると思います。しかし、あなたは整数にスキャンしています。それは、nilの概念がありません。あなたができることの1つは、sql.Scannerインターフェイスを実装するタイプにスキャンして(NULLの値を処理できる)、たとえばsql.NullInt64です。

documentationのサンプルコードでは、username列にNOT NULLという制約があるとします。私はこれが理由だと思うのは、人々があなたのことを信じるように導くことを望まないからです。には、全面的にNULL可能な型を使うのにがあります。

1

私が望む結果を得るためにコードを書き直しました。

// Get the karma value for nick from the database. 
func getKarma(nick string, db *sql.DB) string { 
    var karma int 
    rows, err := db.Query("SELECT SUM(delta) FROM karma WHERE nick = $1", nick) 
    if err != nil { 
     log.Fatal(err) 
    } 
    defer rows.Close() 
    karmaStr := fmt.Sprintf("%s has no karma.", nick) 
    if rows.Next() { 
     rows.Scan(&karma) 
     karmaStr = fmt.Sprintf("Karma for %s is %d.", nick, karma) 
    } 
    return karmaStr 
} 

データベース/ sqlパッケージに何らかの種類のドキュメントパッチを提出することをお断りしました。

+1

ドキュメントパッチは正しいパスのようです。彼らがコードを動作させたいのであれば、実際には、 'email = $ 1 userからselect select id'(メールに一意のインデックスがあると仮定)のように、0行または1行を返すサンプルクエリを使用するべきです。行を常に返す集約(ヌルを含む行さえも)はそれらを破棄しました。 – twotwotwo

+1

ああ、質問のコードは、正確なコードではなく、別のクエリでdocサンプルのバリエーションです。 Spencer Judd氏の説明によれば、問題は、行がない(そして何も返さない)集約型のクエリとNULLを返す集約型のクエリの微妙な違いです。 – twotwotwo

関連する問題