rana/ora.v4连接oracle的示例代码报错 (srvCfg := ora.SrvCfg{Dblink: "orcl"} env.OpenSrv(&srvCfg) )

jimyokl · 2017-06-14 04:36:24 · 3083 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2017-06-14 04:36:24 的主题,其中的信息可能已经有所发展或是发生改变。

错误:

./ocitest.go:17: cannot use &srvCfg (type *ora.SrvCfg) as type ora.SrvCfg in argument to env.OpenSrv

请知道的大神帮忙解答一下,谢谢了 oci8.pc文件内容:

prefix=/usr
version=12.1
build=client64

libdir=/root/program/lib
includedir=/home/oracle_11/app/oracle/product/11.2.0/db_1/rdbms/public

Name: oci8
Description: Oracle database engine
Version: ${version}
Libs: -L${libdir} -lclntsh
Libs.private:
Cflags: -I${includedir}

代码:

package main
import (
    "fmt"
    "gopkg.in/rana/ora.v4"
)

func main() {
    // example usage of the ora package driver
    // connect to a server and open a session
    env, err := ora.OpenEnv()
    defer env.Close()
    if err != nil {
        panic(err)
    }
    srvCfg := ora.SrvCfg{Dblink: "orcl"}
    srv, err := env.OpenSrv(&srvCfg)
    defer srv.Close()
    if err != nil {
        panic(err)
    }
    sesCfg := ora.SesCfg{
        Username: "test",
        Password: "test",
    }
    ses, err := srv.OpenSes(sesCfg)
    defer ses.Close()
    if err != nil {
        panic(err)
    }

    // create table
    tableName := "t1"
    stmtTbl, err := ses.Prep(fmt.Sprintf("CREATE TABLE %v "+
        "(C1 NUMBER(19,0) GENERATED ALWAYS AS IDENTITY "+
        "(START WITH 1 INCREMENT BY 1), C2 VARCHAR2(48 CHAR))", tableName))
    defer stmtTbl.Close()
    if err != nil {
        panic(err)
    }
    rowsAffected, err := stmtTbl.Exe()
    if err != nil {
        panic(err)
    }
    fmt.Println(rowsAffected)

    // begin first transaction
    tx1, err := ses.StartTx()
    if err != nil {
        panic(err)
    }

    // insert record
    var id uint64
    str := "Go is expressive, concise, clean, and efficient."
    stmtIns, err := ses.Prep(fmt.Sprintf(
        "INSERT INTO %v (C2) VALUES (:C2) RETURNING C1 INTO :C1", tableName))
    defer stmtIns.Close()
    rowsAffected, err = stmtIns.Exe(str, &id)
    if err != nil {
        panic(err)
    }
    fmt.Println(rowsAffected)

    // insert nullable String slice
    a := make([]ora.String, 4)
    a[0] = ora.String{Value: "Its concurrency mechanisms make it easy to"}
    a[1] = ora.String{IsNull: true}
    a[2] = ora.String{Value: "It's a fast, statically typed, compiled"}
    a[3] = ora.String{Value: "One of Go's key design goals is code"}
    stmtSliceIns, err := ses.Prep(fmt.Sprintf(
        "INSERT INTO %v (C2) VALUES (:C2)", tableName))
    defer stmtSliceIns.Close()
    if err != nil {
        panic(err)
    }
    rowsAffected, err = stmtSliceIns.Exe(a)
    if err != nil {
        panic(err)
    }
    fmt.Println(rowsAffected)

    // fetch records
    stmtQry, err := ses.Prep(fmt.Sprintf(
        "SELECT C1, C2 FROM %v", tableName))
    defer stmtQry.Close()
    if err != nil {
        panic(err)
    }
    rset, err := stmtQry.Qry()
    if err != nil {
        panic(err)
    }
    for rset.Next() {
        fmt.Println(rset.Row[0], rset.Row[1])
    }
    if err := rset.Err(); err != nil {
        panic(err)
    }

    // commit first transaction
    err = tx1.Commit()
    if err != nil {
        panic(err)
    }

    // begin second transaction
    tx2, err := ses.StartTx()
    if err != nil {
        panic(err)
    }
    // insert null String
    nullableStr := ora.String{IsNull: true}
    stmtTrans, err := ses.Prep(fmt.Sprintf(
        "INSERT INTO %v (C2) VALUES (:C2)", tableName))
    defer stmtTrans.Close()
    if err != nil {
        panic(err)
    }
    rowsAffected, err = stmtTrans.Exe(nullableStr)
    if err != nil {
        panic(err)
    }
    fmt.Println(rowsAffected)
    // rollback second transaction
    err = tx2.Rollback()
    if err != nil {
        panic(err)
    }

    // fetch and specify return type
    stmtCount, err := ses.Prep(fmt.Sprintf(
        "SELECT COUNT(C1) FROM %v WHERE C2 IS NULL", tableName), ora.U8)
    defer stmtCount.Close()
    if err != nil {
        panic(err)
    }
    rset, err = stmtCount.Qry()
    if err != nil {
        panic(err)
    }
    row := rset.NextRow()
    if row != nil {
        fmt.Println(row[0])
    }
    if err := rset.Err(); err != nil {
        panic(err)
    }

    // create stored procedure with sys_refcursor
    stmtProcCreate, err := ses.Prep(fmt.Sprintf(
        "CREATE OR REPLACE PROCEDURE PROC1(P1 OUT SYS_REFCURSOR) AS BEGIN "+
            "OPEN P1 FOR SELECT C1, C2 FROM %v WHERE C1 > 2 ORDER BY C1; "+
            "END PROC1;",
        tableName))
    defer stmtProcCreate.Close()
    rowsAffected, err = stmtProcCreate.Exe()
    if err != nil {
        panic(err)
    }

    // call stored procedure
    // pass *Rset to Exe to receive the results of a sys_refcursor
    stmtProcCall, err := ses.Prep("CALL PROC1(:1)")
    defer stmtProcCall.Close()
    if err != nil {
        panic(err)
    }
    procRset := &ora.Rset{}
    rowsAffected, err = stmtProcCall.Exe(procRset)
    if err != nil {
        panic(err)
    }
    if procRset.IsOpen() {
        for procRset.Next() {
            fmt.Println(procRset.Row[0], procRset.Row[1])
        }
        if err := procRset.Err(); err != nil {
            panic(err)
        }
        fmt.Println(procRset.Len())
    }

    // Output:
    // 0
    // 1
    // 4
    // 1 Go is expressive, concise, clean, and efficient.
    // 2 Its concurrency mechanisms make it easy to
    // 3
    // 4 It's a fast, statically typed, compiled
    // 5 One of Go's key design goals is code
    // 1
    // 1
    // 3
    // 4 It's a fast, statically typed, compiled
    // 5 One of Go's key design goals is code
    // 3
}

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

3083 次点击  
加入收藏 微博
10 回复  |  直到 2017-06-14 06:26:35
polaris
polaris · #1 · 8年之前

根据报错应该这么用:env.OpenSrv(srvCfg),不需要 &

jimyokl
jimyokl · #2 · 8年之前

我觉得官方的代码应该没问题,代码链接:https://github.com/rana/ora

改为 env.OpenSrv(srvCfg) 后编译能通过,但运行时报错:

[root@bogon ocitest]# go install ocitest
[root@bogon ocitest]# /root/tasks/go/fjgd/bin/ocitest 
panic: Parameter 'cfg' may not be empty.

goroutine 1 [running]:
gopkg.in/rana/ora%2ev4.(*Env).OpenSrv(0xc4200842c0, 0x5a7c66, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /root/tasks/go/fjgd/src/gopkg.in/rana/ora.v4/env.go:131 +0x812
main.main()
    /root/tasks/go/fjgd/src/ocitest/ocitest.go:17 +0x130
[root@bogon ocitest]# ll /root/tasks/go/fjgd/bin/ocitest 
-rwxr-xr-x. 1 root root 3951859 6月  13 06:52 /root/tasks/go/fjgd/bin/ocitest
[root@bogon ocitest]# date
2017年 06月 13日 星期二 06:54:29 CST
jimyokl
jimyokl · #3 · 8年之前
jimyokljimyokl #2 回复

我觉得官方的代码应该没问题,代码链接:https://github.com/rana/ora 改为 env.OpenSrv(srvCfg) 后编译能通过,但运行时报错: [root@bogon ocitest]# go install ocitest [root@bogon ocitest]# /root/tasks/go/fjgd/bin/ocitest panic: Parameter 'cfg' may not be empty. goroutine 1 [running]: gopkg.in/rana/ora%2ev4.(*Env).OpenSrv(0xc4200842c0, 0x5a7c66, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...) /root/tasks/go/fjgd/src/gopkg.in/rana/ora.v4/env.go:131 +0x812 main.main() /root/tasks/go/fjgd/src/ocitest/ocitest.go:17 +0x130 [root@bogon ocitest]# ll /root/tasks/go/fjgd/bin/ocitest -rwxr-xr-x. 1 root root 3951859 6月 13 06:52 /root/tasks/go/fjgd/bin/ocitest [root@bogon ocitest]# date 2017年 06月 13日 星期二 06:54:29 CST

谢谢@polaris 我觉得官方的代码应该没问题,代码链接:https://github.com/rana/ora

改为 env.OpenSrv(srvCfg) 后编译能通过,但运行时报错:

[root@bogon ocitest]# go install ocitest
[root@bogon ocitest]# /root/tasks/go/fjgd/bin/ocitest 
panic: Parameter 'cfg' may not be empty.

goroutine 1 [running]:
gopkg.in/rana/ora%2ev4.(*Env).OpenSrv(0xc4200842c0, 0x5a7c66, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /root/tasks/go/fjgd/src/gopkg.in/rana/ora.v4/env.go:131 +0x812
main.main()
    /root/tasks/go/fjgd/src/ocitest/ocitest.go:17 +0x130
[root@bogon ocitest]# ll /root/tasks/go/fjgd/bin/ocitest 
-rwxr-xr-x. 1 root root 3951859 6月  13 06:52 /root/tasks/go/fjgd/bin/ocitest
[root@bogon ocitest]# date
2017年 06月 13日 星期二 06:54:29 CST
polaris
polaris · #4 · 8年之前

我看了下,官方代码,OpenSrv 也参数也是没有 & 的,所以使用是对的。这个错误貌似提示 cfg 是空,这个你可以根据提示排查下。

PS:回复某个楼层,对应楼层会收到通知,不需要额外 @ 了 :smile:

jimyokl
jimyokl · #5 · 8年之前
polarispolaris #4 回复

我看了下,官方代码,OpenSrv 也参数也是没有 & 的,所以使用是对的。这个错误貌似提示 cfg 是空,这个你可以根据提示排查下。 PS:回复某个楼层,对应楼层会收到通知,不需要额外 @ 了 :smile:

不好意思哈,再问一下,我怎么看到的https://github.com/rana/ora 里面的代码有&的:

https://github.com/rana/ora

和 sc := &ora.SrvCfg{Dblink: "orcl"} srv, err := env.OpenSrv(sc)

谢谢了哈,请大佬再帮忙看看

jimyokl
jimyokl · #6 · 8年之前

刚刚发错了:

srvCfg := ora.SrvCfg{Dblink: "orcl"}
srv, err := env.OpenSrv(&srvCfg)
polaris
polaris · #7 · 8年之前

源码 https://github.com/rana/ora/blob/v4.1.9/env.go#L129 接收一个 SrvCfg 实例,而不是指针,它的例子显然有问题。当然更可能的情况是,之前版本是接收指针,后来改了。

jimyokl
jimyokl · #8 · 8年之前
polarispolaris #7 回复

源码 https://github.com/rana/ora/blob/v4.1.9/env.go#L129 接收一个 SrvCfg 实例,而不是指针,它的例子显然有问题。当然更可能的情况是,之前版本是接收指针,后来改了。

感谢你无私的帮助

polaris
polaris · #9 · 8年之前

太客气了

jimyokl
jimyokl · #10 · 8年之前

之前的版本(v3)确实是指针,谢谢

func (env *Env) OpenSrv(cfg *SrvCfg) (srv *Srv, err error) {
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传