這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。 使用glang有一段時間了,最開始其實並不太喜歡他的文法,但是後來熟悉之後發現用起來還挺爽的。之前資料庫一直使用mysql,串連起來沒有什麼問題,github上有很多完善的驅動,所以以為串連其他資料庫也應該沒什麼問題,近日聽說其串連orcale比較麻煩,所以就試了試。
之所以串連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下載地址相關:http://blog.csdn.net/mecho/article/details/24305369
裡邊詳細介紹了 MinGW各版本的不同,可根據自己情況下載,由於我是64位,這裡下載 64位的
POSIX版本 。
具體的安裝過程就不費話了,直接解壓即可。
二、安裝OCI
由於沒有對應驅動包,我們不能直接連接,所以需要通過orcale提供OCI介面(有點像odbc),裡邊包含需要的類庫。下載直接官網就行,找到系統對應版本:
- oci下載地址:http://www.oracle.com/technetwork/topics/winsoft-085727.html
需下載 Basic和SDK,下載後解壓Basic到instantclient_11_1,然後將SDK解壓到 instantclient_11_1\sdk下。
在instantclient_11_1下建立\network\admin\目錄,添加tnsnames.ora(這個就不解釋了吧),內容根據自己的orcale設定。
三、配置go-oci8
直接go get github.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-configprefix=修改為instantclient_11_1目錄,如F:/dev/instantclient_11_1exec_prefix=修改為instantclient_11_1目錄,如F:/dev/instantclient_11_1libdir=${exec_prefix}includedir=${prefix}/sdk/include/Name: OCIDescription: Oracle database engineVersion: 11.2Libs: -L${libdir} -lociLibs.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 get github.com/wendal/go-oci8,如果沒錯那說明大功告成。具體測試代碼見github.com\wendal\go-oci8\example下的oracle.go,注意要把裡邊import中的mattn改成wendal。一下是My Code:
package mainimport ("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 stringrows.Scan(&name)log.Printf("Name = %s, len=%d", name, len(name))}rows.Close()}func update() {// 為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()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()}