在Go中连接到Oracle数据库

我正尝试从Windows(64位Go,32位客户端)连接到Oracle数据库,

我已经回答了这个问题,但我对Go完全陌生,所以对于他所build议的configuration我毫无头绪。

我已经安装了多个客户端,例如:

1. `code.google.com\p\odbc` 2. `github.com\mattn\go-oci8` 

我试图创buildoci8.pc文件,但它似乎是错误的。

 prefix=/devel/target/1.0 exec_prefix=${prefix} libdir=C:/oracle/instantclient_12_1/sdk/lib/msvc includedir=C:/oracle/instantclient_12_1/sdk/include oralib=C:/oracle/instantclient_12_1/sdk/lib/msvc orainclude=C:/oracle/instantclient_12_1/sdk/include gcclib=C:/TDM-GCC-64/lib gccinclude=C:/TDM-GCC-64/include glib_genmarshal=glib-genmarshal gobject_query=gobject-query glib_mkenums=glib-mkenums Name: oci8 Version: 12.1 Description: oci8 library Libs: -L${oralib} -L${gcclib} -loci Libs.private: Cflags: -I${orainclude} -I${gccinclude} 

当我运行下面的代码,我得到错误:

 // TestDB package main import ( "github.com/odbc" ) func main() { conn, _ := odbc.Connect("DSN=lnxcepd1db01.XXXXXX.com:51521*CBPDEV;UID=XXXXX;PWD=XXXXX") defer conn.Close() stmt, _ := conn.Prepare("select * from XXXXX where XXXX = ?") defer stmt.Close() stmt.Execute("100044") rows, _ := stmt.FetchAll() for i, row := range rows { println(i, row) } } 

错误:

 panic: runtime error: invalid memory address or nil pointer dereference panic: runtime error: invalid memory address or nil pointer dereference [signal 0xc0000005 code=0x0 addr=0x8 pc=0x43c3a6] goroutine 1 [running]: github.com/odbc.(*Connection).Close(0x0, 0x45) C:/Go/UDL/src/github.com/odbc/odbc.go:263 +0x26 github.com/odbc.(*Connection).newStmt(0x0, 0x36, 0xc0820120e0) C:/Go/UDL/src/github.com/odbc/odbc.go:152 +0x50 github.com/odbc.(*Connection).Prepare(0x0, 0x51cf70, 0x36, 0x0, 0x0, 0x0, 0xc082005e90, 0x9d6eb0) C:/Go/UDL/src/github.com/odbc/odbc.go:162 +0x51 main.main() C:/Go/My Codes/new/TestDB.go:12 +0xc4 goroutine 17 [syscall, locked to thread]: runtime.goexit() c:/go/src/runtime/asm_amd64.s:2232 +0x1 

我错过了什么? 如果有人能把我指向正确的方向,我将会非常棒。

提前致谢。

编辑:

浏览更多后,我改变了我的代码如下:

 // TestDB package main import ( _ "code.google.com/p/odbc" "database/sql" "fmt" ) func main() { fmt.Println(sql.Drivers()) db, err := sql.Open("odbc","DSN=lnxcepd1db01.xxxx.com:51521*CBPDEV;UID=XXXX;PWD=XXXX") if err != nil { panic(err) } rows, err := db.Query("select TABLE_NAME from tabs") var TABLE_NAME string defer rows.Close() for rows.Next() { fmt.Println(rows.Columns()) rows.Scan(&TABLE_NAME) fmt.Println(TABLE_NAME) } err = rows.Err() if err != nil { panic(err) } defer db.Close() } 

输出+错误堆栈:

 [odbc] panic: runtime error: invalid memory address or nil pointer dereference panic: runtime error: invalid memory address or nil pointer dereference [signal 0xc0000005 code=0x0 addr=0x20 pc=0x453408] goroutine 1 [running]: database/sql.(*Rows).Close(0x0, 0x0, 0x0) c:/go/src/database/sql/sql.go:1659 +0x38 database/sql.(*Rows).Next(0x0, 0xc082002400) c:/go/src/database/sql/sql.go:1586 +0x2c main.main() C:/Go/My Codes/new/TestDB.go:23 +0x263 goroutine 2 [runnable]: runtime.forcegchelper() c:/go/src/runtime/proc.go:90 runtime.goexit() c:/go/src/runtime/asm_amd64.s:2232 +0x1 goroutine 3 [runnable]: runtime.bgsweep() c:/go/src/runtime/mgc0.go:82 runtime.goexit() c:/go/src/runtime/asm_amd64.s:2232 +0x1 goroutine 4 [runnable]: runtime.runfinq() c:/go/src/runtime/malloc.go:712 runtime.goexit() c:/go/src/runtime/asm_amd64.s:2232 +0x1 goroutine 5 [runnable]: database/sql.(*DB).connectionOpener(0xc08205a000) c:/go/src/database/sql/sql.go:588 created by database/sql.Open c:/go/src/database/sql/sql.go:452 +0x323 

正如你所看到的,当我打印可用的驱动程序,我得到odbc ,我不知道我失踪。

我正在使用这个odbc驱动程序。

https://code.google.com/p/odbc/wiki/GettingStartedOnWindows

我注意到1件事情:

当我使用

 db, err := sql.Open("odbc", "DSN=lnxcepd1db01.XXXXX.com:51521;USERID=XXXX;PASSWORD=XXXX;DATABASE=CBPDEV") 

我得到错误,

 %v SQLDriverConnect: {IM002} [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified 

当我尝试,

 db, err := sql.Open("odbc", "DSN=lnxcepd1db01.XXXXXX.com:51521*CBPDEV;UID=XXXX;PWD=XXXXX") 

我收到错误:

 SQLDriverConnect: {IM010} [Microsoft][ODBC Driver Manager] Data source name too long 

还有这个:

 db, err := sql.Open("odbc","DSN=lnxcepd1db01.XXXXX.com:51521*cbpdev;UID=XXX;PWD=XXXX") 

错误:

 SQLDriverConnect: {IM010} [Microsoft][ODBC Driver Manager] Data source name too long 

我完全失了,因为我不能将此与驱动程序问题,我的代码问题或我缺less连接string中的一些参数。

我有以下问题:

我的连接string有什么问题? 有没有人有一个工作的设置或指示要从APIbuild设开始(我很抱歉,但我尝试了一些,但没有运气)? 哪个API更好或更易于使用?

这里是一个完成conn / prep / query / fetch操作的函数:

 func getDatePrepQuery(driver string, connString string) error { db, err := sql.Open(driver, connString) if err != nil { log.Printf("sql.Open(%s, %s)\n\t%s\n", driver, connString, err.Error()) return err } defer db.Close() query := "select SYSDATE from dual" stmt, err := db.Prepare(query) if err != nil { log.Printf("db.Prepare(%s) failed.\n\t%s\n", query, err.Error()) return err } defer stmt.Close() rows, err := stmt.Query() if err != nil { log.Printf("stmt.Query() failed.\n\t%s\n", err.Error()) return err } defer rows.Close() var columns []string columns, err = rows.Columns() if err != nil { log.Printf("rows.Columns() failed.\n\t%s\n", err.Error()) } for i, c := range columns { fmt.Printf("%3d %s\n", i, c) } for rows.Next() { var sysdate time.Time err = rows.Scan(&sysdate) if err != nil { log.Printf("rows.Scan(...) failed.\n\t%s\n", err.Error()) return err } fmt.Println("SYSDATE:", sysdate) } err = rows.Err() if err != nil { log.Printf("rows iteration failed.\n\t%s\n", err.Error()) return err } return nil } 

使用扫描是一个棘手的部分,因为它可能不是Oracle程序员习惯的东西。 这个函数适用于我尝试的所有odbc,mgodbc,oci8,adodb和goracle包。

你得到的错误说你试图访问一个非初始化变量(无值)的“方法”。 在使用返回的值之前,你应该检查你没有错误。

 package main import ( "github.com/odbc" "log" ) func main() { conn, err := odbc.Connect("DSN=lnxcepd1db01.XXXXXX.com:51521*CBPDEV;UID=XXXXX;PWD=XXXXX") if err != nil { log.Println(log) return } defer conn.Close() stmt, err := conn.Prepare("select * from XXXXX where XXXX = ?") if err != nil { log.Println(log) return } defer stmt.Close() stmt.Execute("100044") rows, _ := stmt.FetchAll() for i, row := range rows { println(i, row) } }