66077


go と database/sql を使って以下のようなコードを書きました。  
やりたい事としては、hoge テーブルからデータを select して、その内容を取得する事です。

DB のデータ構造は構造体におこさない条件があります。

`*val` には DB から取得した値が入る想定でしたが、数値の配列が入っています。  
この数値は何を表しているのでしょうか？ また、正しくレコードの値を取得する方法があれば教えていただきたいです。

[code]

    rows, err := db.Query("select * from hoge")
    if err != nil {
        return err
    }
    columns, err := rows.Columns()
    if err != nil {
        return err
    }
    
    count := len(columnNames)
    args := make([]interface{}, count)
    pointers := make([]interface{}, count)
    
    for i, _ := range args {
        pointers[i] = &args[i]
    }
    
    for rows.Next() {
        err := rows.Scan(pointers...)
        if err != nil {
            return err
        }
        for i, n := range columnNames {
            val := pointers[i].(*interface{})
            log.Println(*val) // [50 48 50 48 45 48 51 45 48 54 32 49 50 58 53 56 58 52 55]
        }
        ...
    
[/code]


CC BY-SA 4.0
2020-04-27T15:45:02.173
66039
2020-04-28T13:35:44.463
2020-04-27T16:37:13.497
3060
10865
question
sql go database
go と database/sql で構造体がない場合でも値を取得したい。


データベーステーブルのカラム情報を、[sql.Rows.ColumnTypes()](https://golang.org/pkg/database/sql/#Rows.ColumnTypes)
と
[sql.ColumnType.ScanType()](https://golang.org/pkg/database/sql/#ColumnType.ScanType)
を利用して取得するサンプルプログラムを以下に示します。データベースは sqlite3 を使用しています。

`reflect.New()` で各カラムに対応する Go の型(type)のインスタンス(ポインタ)を作成して、それらを
`sql.Rows.Scan()` に渡しています。ポインタですので、値を取り出すのに `reflect.Value.Elem()` を使います。

**sql_example.go**

[code]

    package main
    
    import (
        "database/sql"
        "fmt"
        "reflect"
    
        _ "github.com/mattn/go-sqlite3"
    )
    
    func main() {
        // Connect to database
        db, err := sql.Open("sqlite3", "./test.db")
        if err != nil {
            panic(err)
        }
        defer db.Close()
    
        // Select records
        rows, err := db.Query("SELECT * from hoge")
        if err != nil {
            panic(err)
        }
        defer rows.Close()
    
        // No records
        if !rows.Next() {
            return
        }
    
        // Column types
        ct, err := rows.ColumnTypes()
        if err != nil {
            panic(err)
        }
        types := make([]reflect.Type, len(ct))
        for i, typ := range ct {
            types[i] = typ.ScanType()
        }
    
        // Column values
        values := make([]interface{}, len(ct))
        for i := range values {
            values[i] = reflect.New(types[i]).Interface()
        }
    
        // Scan
        for {
            err := rows.Scan(values...)
            if err != nil {
                panic(err)
            }
    
            for _, v := range values {
                fmt.Printf("%v|", reflect.ValueOf(v).Elem())
            }
            fmt.Println()
    
            if !rows.Next() {
                break
            }
        }
    }
    
[/code]

**実行結果**

[code]

    $ sqlite3 test.db <<EOS
    CREATE TABLE hoge (
      id INTEGER PRIMARY KEY,
      created_at TIMESTAMP DEFAULT (datetime(CURRENT_TIMESTAMP, 'localtime'))
    );
    INSERT INTO hoge VALUES (1, '2020-03-06 12:58:47');
    INSERT INTO hoge VALUES (2, '2020-04-28 01:36:20');
    INSERT INTO hoge VALUES (3, '2020-05-15 15:10:12');
    EOS
    
    $ sqlite3 test.db <<EOS
    SELECT * from hoge;
    EOS
    1|2020-03-06 12:58:47
    2|2020-04-28 01:36:20
    3|2020-05-15 15:10:12
    
    $ go run sql_example.go
    1|2020-03-06T12:58:47Z|
    2|2020-04-28T01:36:20Z|
    3|2020-05-15T15:10:12Z|
    
[/code]


CC BY-SA 4.0
2020-04-28T13:35:44.463
66077
2020-04-28T13:35:44.463
66039
answer