sijms / go-ora

Pure go oracle client
MIT License
767 stars 168 forks source link

Can't query BLOB data (version 2.8.9) #524

Closed zhanghaiyang9999 closed 4 months ago

zhanghaiyang9999 commented 4 months ago

Please see the following codes, the column_6 is BLOB type. it's very easy to reproduce.

rowst, errt := conn.Query("SELECT column_6 from table_all where ID=89") if errt != nil { return }

var (
    data3 []byte
)
for rowst.Next() {
    err := rowst.Scan(&data3)
    if err != nil {
        return
    }

}
rowst.Close()

the return value data3 is nil, please see the screenshot. image

sijms commented 4 months ago

the code:

package main

import (
    "database/sql"
    "fmt"
    _ "github.com/sijms/go-ora/v2"
    "os"
    "strconv"
    "time"
)

func execCmd(db *sql.DB, stmts ...string) error {
    for _, stmt := range stmts {
        if _, err := db.Exec(stmt); err != nil {
            if len(stmts) > 1 {
                return fmt.Errorf("error: %v in execuation of stmt: %s", err, stmt)
            } else {
                return err
            }
        }
    }
    return nil
}

func createTable(db *sql.DB) error {
    t := time.Now()
    err := execCmd(db, `CREATE TABLE TTB_524(
    ID  number(10)  NOT NULL,
    DATA BLOB,
    PRIMARY KEY(ID)
    )`)
    if err != nil {
        return err
    }
    fmt.Println("Finish create table :", time.Now().Sub(t))
    return nil
}

func dropTable(db *sql.DB) error {
    t := time.Now()
    err := execCmd(db, "drop table TTB_524 purge")
    if err != nil {
        return err
    }
    fmt.Println("Finish drop table: ", time.Now().Sub(t))
    return nil
}

func insertData(conn *sql.DB) error {
    type TTB_DATA struct {
        Id   int    `db:"ID"`
        Data []byte `db:"DATA"`
    }
    t := time.Now()
    data := make([]TTB_DATA, 100)
    for x := 0; x < 100; x++ {
        data[x].Id = 1 + x
        if x == 5 {
            data[x].Data = nil
        } else {
        data[x].Data = []byte("test_" + strconv.Itoa(x))
        }
    }
    _, err := conn.Exec("INSERT INTO TTB_524 (ID, DATA) VALUES(:ID, :DATA)", data)
    if err != nil {
        return err
    }
    fmt.Println("Finish insert data: ", time.Now().Sub(t))
    return nil
}

func query(db *sql.DB) error {
    rows, err := db.Query("SELECT ID, DATA FROM TTB_524")
    if err != nil {
        return err
    }
    defer func() {
        err = rows.Close()
        if err != nil {
            fmt.Println("can't close rows")
        }
    }()
    var (
        id   int
        data []byte
    )
    for rows.Next() {
        err = rows.Scan(&id, &data)
        if err != nil {
            return err
        }
        fmt.Println("ID: ", id, "\tDATA: ", string(data))
    }
    return rows.Err()
}
func main() {
    db, err := sql.Open("oracle", os.Getenv("DSN"))
    if err != nil {
        fmt.Println("can't connect: ", err)
        return
    }
    defer func() {
        err = db.Close()
        if err != nil {
            fmt.Println("can't close connection: ", err)
        }
    }()

    err = createTable(db)
    if err != nil {
        fmt.Println("Can't create table: ", err)
        return
    }
    defer func() {
        err = dropTable(db)
        if err != nil {
            fmt.Println("Can't drop table: ", err)
        }
    }()

    err = insertData(db)
    if err != nil {
        panic(err)
    }
    err = query(db)
    if err != nil {
        panic(err)
    }
}

the result:

Finish create table : 1.127179437s
Finish insert data:  125.773071ms
ID:  1  DATA:  test_0
ID:  2  DATA:  test_1
ID:  3  DATA:  test_2
ID:  4  DATA:  test_3
ID:  5  DATA:  test_4
ID:  6  DATA:  
ID:  7  DATA:  test_6
ID:  8  DATA:  test_7
ID:  9  DATA:  test_8
ID:  10     DATA:  test_9
ID:  11     DATA:  test_10
.
.
.
.
ID:  91     DATA:  test_90
ID:  92     DATA:  test_91
ID:  93     DATA:  test_92
ID:  94     DATA:  test_93
ID:  95     DATA:  test_94
ID:  96     DATA:  test_95
ID:  97     DATA:  test_96
ID:  98     DATA:  test_97
ID:  99     DATA:  test_98
ID:  100    DATA:  test_99
Finish drop table:  151.928078ms