猿问

如何将图像作为 BLOB 插入 Oracle 数据库

我有一个带有 A_LOB_TABLE 表的数据库:


我想使用 goracle 包将具有任何(假设为“1”)ID 的 BLOB 图像插入到 A_LOB_TABLE 中。


这是我的代码:


ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)

defer cancel()


// To have a valid LOB locator, we have to keep the Stmt around.

qry := `DECLARE tmp BLOB;

BEGIN

  DBMS_LOB.createtemporary(tmp, TRUE, DBMS_LOB.SESSION);

  :1 := tmp;

END;`

    tx, err := testDb.BeginTx(ctx, nil)

    if err != nil {

        fmt.Println(err)

    }

    defer tx.Rollback()


stmt, err := tx.PrepareContext(ctx, qry)

if err != nil {

    fmt.Printf("%s: %w", qry, err)

}

defer stmt.Close()

var tmp goracle.Lob

if _, err := stmt.ExecContext(ctx, goracle.LobAsReader(), sql.Out{Dest: &tmp}); err != nil {

    fmt.Printf("Failed to create temporary lob: %+v", err)

}

fmt.Printf("tmp: %#v", tmp)


// Get file as bytes (it needs to be in the same dir as code is)

dat, err := ioutil.ReadFile("./sample.png")

if err != nil {

    fmt.Println(".....Error Opening File")

    fmt.Println(err)

    return

}


if _, err := tx.ExecContext(ctx,

    "BEGIN dbms_lob.append(:1, :2); END;",

    tmp, goracle.Lob{Reader: bytes.NewReader(dat[:])},

); err != nil {

    fmt.Printf("Failed to write buffer(%v) to lob(%v): %+v", dat, tmp, err)

}


// INSERTING LOB - starting....

_, err = testDb.Exec("insert into A_LOB_TABLE(id, image) VALUES(:1, :2)",  1, tmp)

if err != nil {

    fmt.Println(".....Error Inserting data - BLOB")

    fmt.Println(err)

    return

}

// INSERTING LOB - ended.

但这不起作用。它在行输出错误


_, err = testDb.Exec("insert into A_LOB_TABLE(id, image) VALUES(:1, :2)",  1, tmp)

说:


dpiStmt_execute(mode=32 arrLen=-1): ORA-22922: LOB 值不存在


有只小跳蛙
浏览 162回答 1
1回答

慕尼黑的夜晚无繁华

经过数十个小时尝试弄清楚如何使用 goracle Go 驱动程序将 BLOB 插入到 OracleDB 中,我得到了答案。长话短说完整代码(显然根据您的需要调整数据库连接和文件位置&&文件名等变量):package mainimport (    "bytes"    "context"    "database/sql"    "fmt"    "io/ioutil"    "time"goracle "gopkg.in/goracle.v2")func main() {    fmt.Println("... Setting up Database Connection")    testDb, err := sql.Open("goracle",        "sys" +            "/" +            "Oracle18" +            "@" +            "localhost:32118" +            "/" +            "XE as sysdba")    if err != nil {        fmt.Println("... DB Setup Failed")        fmt.Println(err)        return    }    defer testDb.Close()// Get file as bytesdat, err := ioutil.ReadFile("./sample.png")if err != nil {    fmt.Println(".....Error Opening File")    fmt.Println(err)    return}// BLOB creation && passing file into itdirectLob := goracle.Lob{ Reader: bytes.NewReader(dat[:])}fmt.Println("\nINSERTING BLOB - starting....")// Working BLOB insertion - INSERT COMMAND_, err = testDb.Exec("insert into AA_LIVE_FRAMES(id, frame) VALUES(:1, :2)",  1, directLob)if err != nil {    fmt.Println(".....Error Inserting BLOB")    fmt.Println(err)    return}fmt.Println("\nINSERTING BLOB - ended.")fmt.Println("\nSuccess")}这是正在运行的 main.go 文件。较长版本的答案如果代码如此简单,为什么我花了这么长时间?当我开始解决这个问题时,我在 goracle 文档中没有找到任何说明如何将 BLOB 插入 OracleDB 的教程或示例。当然,这个 goracle.Lob 结构具有很好的功能 - Read()。这是我第一次尝试,声明这个 goracle.Lob 并使用它的 Read() 函数,但它给了我错误 - nil 地址等等。我不知道为什么,尝试调试它 - 没有结果。然后我更深入,我从 goracle 包中提取了一些测试代码,展示了如何创建临时 LOB - 其中一些代码显示在我的问题答案中。再次,没有成功。然后,我尝试原始 SQL,再次失败(我认为因为我的 OracleDB 是 docker - 创建目录,将 BLOB 插入 OracleDB 所需的目录不起作用;nvm)。最后,我不知道为什么,我尝试过结构文字:directLob := goracle.Lob{ Reader: bytes.NewReader(dat[:])}并工作了。好吧,为什么我要输入这些内容?因为,据我所知,这样做:directLob := goracle.Lob{ Reader: bytes.NewReader(dat[:])}和这个:directLob := goracle.Lob{}directLob.Read(dat[:])应该是一样的吗?或者我完全错了?
随时随地看视频慕课网APP

相关分类

Go
我要回答