1. 程式人生 > >golang ODBC 訪問access資料庫

golang ODBC 訪問access資料庫

最近專案需要,需要操作access,以前是用VC++ OLE訪問,網路用ACE庫,感覺很龐大。。。決定用go試試

安裝方式如下:

ODBC database driver for Go

Install:
	cd $GOPATH/src
	git clone git://github.com/weigj/go-odbc.git odbc
	cd odbc
	go install

測試時碰到好多坑。。。。。

第1次當執行go install時,

坑爹1:發現找不到gcc,哦, 推測cgo去連結odbc32的dll,需要gcc編譯環境,幸虧哥搞cocos2d-x時電腦上已經裝了龐大的cygwin,於是啟動Cygwin Terminal,跳轉到odbc目錄,

第2次當執行go install時,

坑爹2:提示access limit。。可是在console裡直接執行gcc -v是存在的,感覺是gcc這個是linux的符號連結,推測go install時可能沒用利用cygwin的環境設定,有點衝突,於是刪掉gcc這個符號link,把真正的gcc-4.exe改名為gcc.exe,

第3次當執行go install時,

坑爹3:提示找不到ODBC的函式符號,你妹,不得不fuck source code了,讀原始碼odbc.go,發現匯入有個macro定義,
#ifdef __MINGW32__
  #include <windef.h>
#else
  typedef void* HANDLE;
#endif
原來odbc.go編譯依賴MINGW環境,於是下載mingw,安裝完後,把mingw的bin目錄加到系統path裡,編譯成功。

go run 下面的例子程式碼,

package main

import (
	"database/sql"
	"fmt"
	_ "odbc/driver"
)

func main() {
	conn, err := sql.Open("odbc", "driver={Microsoft Access Driver (*.mdb)};dbq=d:\\test.mdb")
	if err != nil {
		fmt.Println("Connecting Error")
		return
	}
	defer conn.Close()
	stmt, err := conn.Prepare("select * from test") //ALTER TABLE tb ALTER COLUMN aa Long
	if err != nil {
		fmt.Println("Query Error")
		return
	}
	defer stmt.Close()
	row, err := stmt.Query()
	if err != nil {
		fmt.Print(err)
		fmt.Println("Query Error")
		return
	}
	defer row.Close()
	for row.Next() {
		var ID string
		var SequenceNumber int
		var ValueCode string
		if err := row.Scan(&ID, &SequenceNumber, &ValueCode); err == nil {
			fmt.Println(ID, SequenceNumber, ValueCode)
		}
	}
	fmt.Printf("%s\n", "finish")
	return
}
坑爹4:居然提示
fatal error: malloc/free - deadlock
	[signal 0xc0000005 code=0x1 addr=0x2f0 pc=0x419258]
	
	goroutine 1 [syscall]:
	[fp=0x10815fc] return()
		C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist465310315/go/src/pkg/runtime/asm_386.s:472
	[fp=0x1081624] runtime.cgocall(0x470a23, 0x1081630)
		C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist465310315/go/src/pkg/runtime/cgocall.c:162 +0x10a
	[fp=0x1081630] odbc._Cfunc_SQLFreeHandle(0x400003, 0xb115e8, 0x1081650)
		C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/go-build619492171/odbc/_obj/_cgo_defun.c:144 +0x31
	[fp=0x1081640] odbc.(*Statement).free(0x2f860140)
		odbc.go:745 +0x32
	[fp=0x1081648] odbc.(*Statement).Close(0x2f860140)
		odbc.go:752 +0x28
	[fp=0x1081650] odbc/driver.(*stmt).Close(0x2f860148, 0x2f8601c8, 0x405a2b)
		E:/go/src/odbc/driver/sql.go:107 +0x2a
	[fp=0x108168c] database/sql.(*DB).noteUnusedDriverStatement(0x2f884300, 0x2f8821e0, 0x2f882240, 0x2f860148)
		C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist465310315/go/src/pkg/database/sql/sql.go:554 +0x17a
	[fp=0x10816d0] database/sql.(*Stmt).finalClose(0x2f8862d0, 0x2f8601b8, 0x0)
		C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist465310315/go/src/pkg/database/sql/sql.go:1264 +0x84
	[fp=0x10816e0] database/sql.func·002(0x2f884310, 0x2f894720)
		C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist465310315/go/src/pkg/database/sql/sql.go:372 +0x2c
	[fp=0x1081700] database/sql.(*DB).removeDep(0x2f884300, 0x2f894720, 0x2f8862d0, 0x49c740, 0x2f8862d0, ...)
		C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist465310315/go/src/pkg/database/sql/sql.go:351 +0x78
	[fp=0x1081720] database/sql.(*Stmt).Close(0x2f8862d0, 0x0, 0x0)
		C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist465310315/go/src/pkg/database/sql/sql.go:1259 +0x117
	[fp=0x10817c4] main.main()
		E:/go/src/testaccessdb/testdb.go:12 +0xbf
	[fp=0x10817dc] runtime.main()
		C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist465310315/go/src/pkg/runtime/proc.c:182 +0x8e
	[fp=0x10817e0] runtime.goexit()
		C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist465310315/go/src/pkg/runtime/proc.c:1223
	
	goroutine 2 [syscall]:
	exit status 2

這鬱悶了,google了半天也沒有解決方案,發現golang issue裡有這個問題,可是那貨說最新的go version已經解決了,可哥就是最新的版本啊,順手甚至提交這個bug到golang,決定放棄了。。。。。

可是哥的鑽研精神此刻閃閃發光,照亮我的前程了,反覆N遍,逐漸刪除測試程式碼,最後發現

 stmt.Query()
這個函式刪掉就pass了!

於是仔細讀上面的堆疊垃圾資訊發現問題可能是free 控制代碼odbc._Cfunc_SQLFreeHandle多次導致,懷疑是這個github.com/weigj/go-odbc.git 庫自帶的bug,不是go的問題,於是使用已經廣而知之神器武功套路log大法,在free函式開始和結束處 加log, go run again發現free()函式果然被呼叫了兩次。。。

於是哥修改
func (stmt *Statement) free() {
C.SQLFreeHandle(C.SQL_HANDLE_STMT, stmt.handle)
}

func (stmt *Statement) free() {
if stmt.handle != nil {
C.SQLFreeHandle(C.SQL_HANDLE_STMT, stmt.handle)
stmt.handle = nil
}
}

預期中的測試通過。。。錯誤提示沒有了,只有閃閃發光的finish。。。

善後:尼瑪,發現這作者兩年沒更新,而網上的程式碼片段都指向這個庫。。。於是哥提交了一份修復bug的完整程式碼,請參考https://github.com/philsong/golang_samples

問題解決了,感覺這個庫不是很成熟,不過寫tool utility可以湊合用。

相關推薦

golang ODBC 訪問access資料庫

最近專案需要,需要操作access,以前是用VC++ OLE訪問,網路用ACE庫,感覺很龐大。。。決定用go試試 安裝方式如下: ODBC database driver for Go Install: cd $GOPATH/src git clone git

Python通過pypyodbc訪問Access資料庫

        看書上通過ODBC訪問資料庫的案例,想實踐一下在Python 3.6.1中實現access2003資料庫的連結,但是在匯入odbc模組的時候出現了問題,後來查了一些資料就嘗試著使用py

一次Delphi訪問access資料庫的總結

由於專案需要寫一個門禁介面,要使用Delphi訪問access資料庫的一個表,不得已要使用以前都沒用過的access資料庫,現在介面寫的差不多了,把自己在這當中學到的一些access記一下,以免到時候遺忘。 1、首先要明確access是一個檔案型資料庫,訪問時不需要ip地址

C#Winform連線並訪問Access資料庫

C#Winform連線並訪問Access資料庫 Access新建了一個名為user的資料庫,其中有張名為UserInfor的表。將之添入專案中後,訪問資料表中資料。這樣做: OleDbConne

VBA訪問access資料庫例項

Sub DaoChuExl()          Dim conn As New ADODB.Connection     Dim rs As New ADODB.Recordset     Dim rowxh As Integer, vhx As Integer, rowzs As Integer, con

win7下執行ASP出現不能訪問ACCESS資料庫的問題

在WIN7下士可以除錯ASP程式的,這個過程設定時很簡單的。 但是筆者在配置過程中,發現單純的ASP是可以正常訪問,發現只要是涉及資料庫Access操作就出現錯誤。 發現只要在配置IIS時候,把WEB管理工具全部選上,然後在【執行】處輸入:CSCRIPT %SYSTEMDR

ODBC訪問帶密碼的access資料庫

法1,建立資料來源時解鎖: 建立資料來源有兩種方式,一是手動建立(到控制面板下);二是用程式碼建立(見 動態建立資料來源 )。 但是如果想在建立資料來源的同時解鎖,就只能採用手動的方式了: 只需在輸入了資料來源名之後點“高階”,然後輸入登陸名(可任取)及密碼(即access

通過JDBC-ODBC訪問MySQL資料庫

       通過JDBC-ODBC橋的方式訪問資料庫,需要經過多層的呼叫,因此利用JDBC-ODBC橋訪問資料庫的效率比較低。不過在資料沒有提供JDBC驅動而只有ODBC驅動的情況下,也只能利用JDBC-ODBC橋的方式訪問資料庫。本示例通過JDBC-ODBC橋的方式訪問M

員工請假管理系統(MFC+ACCESS資料庫+ODBC資料來源)

主要介面:(未新增面板) 登陸介面: 主介面: 1.題目要求 用MFC和ACCESS資料庫設計一個請假管理系統可以進行對員工請假的管理和對公司假期及國定假期的設定。 2.功能需求       2.1.系統管理        更換登入使用者       退出    

pyodbc訪問資料庫(python ODBC訪問資料庫

入門 連線到資料庫 呼叫connect方法並傳入ODBC連線字串,其會返回一個connect物件。通過connect物件,呼叫cursor()方法,可以獲取一個遊標cursor。如下程式碼示例: import pyodbc #連線示例: Windows系統, 非DSN方

vs2008 MFC訪問Access 2010資料庫

    MSDN給出了各種語言訪問Access 2010的詳細介紹:點選開啟連結。下圖列出了各種語言訪問Access 2010的介面。 我在VS2008下使用MFC下的ODBC相關介面訪問Access 2010資料庫。 Demo中使用MFC訪問資料庫accsess2010

關於windows2008r2下access資料庫網站報Microsoft OLE DB Provider for ODBC Drivers 錯誤 '80004005'

今天配置站點時報: "Microsoft OLE DB Provider for ODBC Drivers錯誤 '80004005' [Microsoft][ODBC 驅動程式管理器] 未發現數據源名稱並且未指定預設驅動程式 "錯誤,只要把該站點的應用程式池,高階中的啟用32

詳細介紹—獲取ACCESS資料庫中所有的表名(ODBC + MFC實現)解決方法

網上關於獲取ACCESS資料庫中所有的表名的文章挺多的,但是說的不是很詳細,對於初學者來說很難看懂(我也是初學者呵呵),研究了很久,自己弄懂後,覺得很有必要做個詳細的介紹,以免其他初學者向我一樣,因為研究這個東西走很多彎路從而浪費過多寶貴的時間。  獲取ACCESS資料庫中

在VC++中用ODBC訪問SQL Server資料庫

   ODBC(Open Database Connectivity,開放資料庫連線)是由Microsoft定義的一種資料庫訪問標準,它提供了一種標準的資料庫訪問方法以訪問不同資料庫提供商的資料庫,其本質上是一組資料庫訪問API.雖然資料庫訪問有多種方法,但ODBC以其程式

實現JDBC-ODBC橋連線到Access資料庫

如何實現JDBC-ODBC橋連線到Access? (讓你對java執行環境有更好的瞭解) 1、        首先要建立ODBC資料來源,我的系統是Win8.1系統,所以依次選擇“控制面板----管理工具----資料來源(ODBC)”,開啟資料來源管理器,如圖所示: 根據

php+odbc+access 資料庫操作函式,在windows下測試通過

前些天下載了adodb,想用adodb連access資料庫,後來連是連上了,不過不能更新和插入記錄,也不知道為什麼到現在還沒人給我回答那個苦惱的問題,後來就放棄了adodb,使用php自己的odbc,但是使用很不方便,就寫下了下面這些函式,還沒有封裝成類,希望能夠為有同樣問題

用ADO常用的連線方式和訪問加密的ACCESS資料庫

在stdafx.h中新增一句指令: #import "c:\program files\common files\system\ado\msado15.dll" \ no_namespace \ rename ("EOF", "adoEOF") COM庫的初始化在CWi

在java中實現access資料庫的遠端訪問

遠端伺服器中的access資料庫, 1、先在遠端伺服器上配置資料來源 2、下載RmiJdbc.jar包,在遠端伺服器上安裝jdk,配置環境變數,將jar包的路徑配置到classpath中 3、通過 java org.objectweb.rmijdbc.RJJdbcServe

應用 SQLServer 連結伺服器訪問遠端 Access 資料庫

    Web 開發中,經常要用到 Access 資料庫。但是由於 Access 是一種檔案型資料庫,所以無法跨伺服器進行訪問。經過筆者的探索,發現可以利用 SQL Server 的連結伺服器,把地理上分散的 Access 資料庫整合起來,使 Access 資料庫具有跨越 W

基於gin的golang web開發:訪問mysql資料庫

web開發基本都離不開訪問資料庫,在Gin中使用mysql資料庫需要依賴mysql的驅動。直接使用驅動提供的API就要寫很多樣板程式碼。你可以找到很多擴充套件包這裡介紹的是jmoiron/sqlx。另外還有一個用來處理空值的包guregu/null。 ``` go get github.com/go-sql