之所以连接orcale比较麻烦是因为orcale并没有提供golang的驱动,所以并不能像java那样引入个驱动包就能连接,也不能像MysqL之类的开源数据库可以自己实现驱动。不过正所谓天无绝人之路,既然纯go实现不了,那么还可以用cgo实现,c语言总该支持了吧。
网上有很多方法,不过都是使用oci实现的,这里我们使用go-oci8(https://github.com/wendal/go-oci8)
一、安装MinGW
首先我们先来配置环境,由于cgo需要gcc支持,所以需要配置gcc环境,如果是linux下一般可以跳过该步骤,win下则需要自己安装了,这里我们使用 MinGW ,可以到官网现下载,不过官网直接提供的安装程序需要安装时联网下载,很可能会失败,所以几经搜索之后找到如下网址: 里边详细介绍了 MinGW各版本的不同,可根据自己情况下载,由于我是64位,这里下载 64位的POSIX版本 。具体的安装过程就不费话了,直接解压即可。
二、安装OCI
由于没有对应驱动包,我们不能直接连接,所以需要通过orcale提供OCI接口(有点像odbc),里边包含需要的类库。下载直接官网就行,找到系统对应版本:- oci下载地址:http://www.oracle.com/technetwork/topics/winsoft-085727.html
在instantclient_11_1下建立\network\admin\目录,添加tnsnames.ora(这个就不解释了吧),内容根据自己的orcale设置。
三、配置go-oci8
直接go getgithub.com/wendal/go-oci8(报错不用管),然后到go\src\github.com/wendal\go-oci8\windows下,将pkg-config.exe拷贝到MinGW\bin下,将oci8.pc复制到MinGW\lib\pkg-config\下,并且编辑oci8.pc:# Package Information for pkg-config prefix=修改为instantclient_11_1目录,如F:/dev/instantclient_11_1 exec_prefix=修改为instantclient_11_1目录,如F:/dev/instantclient_11_1 libdir=${exec_prefix} includedir=${prefix}/sdk/include/ Name: OCI Description: Oracle database engine Version: 11.2 Libs: -L${libdir} -loci Libs.private: Cflags: -I${includedir}
四、设置环境变量
环境变量path下添加instantclient_11_1和 mingw\bin的路径添加PKG_CONFIG_PATH=C:\mingw\lib\pkg-config
添加TNS_ADMIN= F:\dev\instantclient_11_1 \ network\admin\
五、测试
在此执行go getgithub.com/wendal/go-oci8,如果没错那说明大功告成。具体测试代码见github.com\wendal\go-oci8\example下的oracle.go,注意要把里边import中的mattn改成wendal。一下是我的代码:package main import ( "database/sql" _ "github.com/wendal/go-oci8" "log" ) func query() { // 为log添加短文件名,方便查看行数 log.SetFlags(log.Lshortfile | log.LstdFlags) // 用户名/密码@实例名 跟sqlplus的conn命令类似 db,err := sql.Open("oci8","username/pwd@ORCL") if err != nil { log.Fatal(err) } defer db.Close() rows,err := db.Query("select name from FUB_B") if err != nil { log.Fatal(err) } for rows.Next() { var name string rows.Scan(&name) log.Printf("Name = %s,len=%d",name,len(name)) } rows.Close() } func update() { // 为log添加短文件名,"username/pwd@ORCL") if err != nil { log.Fatal(err) } defer db.Close() stmt,_ := db.Prepare(`UPDATE FUB_B set name ='cnm'`) result,err := stmt.Exec() if err != nil { log.Fatal(err) } count,_ := result.RowsAffected() log.Printf("result count:%d",count) } func main() { update() }