Go 1.1.1 和 ODBC 连接 MSSQL 数据库

6

目前已经运行了 FreeTDS 0.92.4 / unixODBC 2.3.1,并成功连接了 MSSQL 服务器,并能够执行查询等操作。

我找到了这个 Go 语言的 ODBC 实现列表,并尝试了其中粗体标出的两个:


mgodbc

我收到了一堆弃用警告 (从头信息看,它们在OSX 10.8及更高版本中被弃用):

cc1: warnings being treated as errors
mgodbc.go: In function 'mSQLColAttribute':
mgodbc.go:31: warning: 'SQLColAttributeW' is deprecated (declared at /usr/include/sqlucode.h:128)
mgodbc.go: At top level:
mgodbc.go:44: warning: 'SQLDisconnect' is deprecated (declared at /usr/include/sql.h:896)
mgodbc.go:51: warning: 'SQLGetDiagRecW' is deprecated (declared at /usr/include/sqlucode.h:233)
mgodbc.go:62: warning: 'SQLGetInfoW' is deprecated (declared at /usr/include/sqlucode.h:273)
mgodbc.go:67: warning: 'SQLBindParameter' is deprecated (declared at /usr/include/sqlext.h:2519)
mgodbc.go:70: warning: 'SQLDriverConnectW' is deprecated (declared at /usr/include/sqlucode.h:336)
mgodbc.go:73: warning: 'SQLSetEnvAttr' is deprecated (declared at /usr/include/sql.h:1120)
mgodbc.go:74: warning: 'SQLFreeHandle' is deprecated (declared at /usr/include/sql.h:942)
mgodbc.go:75: warning: 'SQLSetConnectAttrW' is deprecated (declared at /usr/include/sqlucode.h:245)
mgodbc.go:78: warning: 'SQLGetDiagFieldW' is deprecated (declared at /usr/include/sqlucode.h:223)
mgodbc.go:82: warning: 'SQLRowCount' is deprecated (declared at /usr/include/sql.h:1076)
mgodbc.go:98: warning: 'SQLGetData' is deprecated (declared at /usr/include/sql.h:975)
mgodbc.go:99: warning: 'SQLEndTran' is deprecated (declared at /usr/include/sql.h:902)
mgodbc.go:102: warning: 'SQLCloseCursor' is deprecated (declared at /usr/include/sql.h:831)
mgodbc.go:103: warning: 'SQLPrepareW' is deprecated (declared at /usr/include/sqlucode.h:239)
mgodbc.go:107: warning: 'SQLNumResultCols' is deprecated (declared at /usr/include/sql.h:1058)
mgodbc.go:113: warning: 'SQLAllocHandle' is deprecated (declared at /usr/include/sql.h:799)
mgodbc.go:114: warning: 'SQLExecute' is deprecated (declared at /usr/include/sql.h:921)
mgodbc.go:115: warning: 'SQLFetch' is deprecated (declared at /usr/include/sql.h:924)
mgodbc.go:119: warning: 'SQLNumParams' is deprecated (declared at /usr/include/sqlext.h:2448)

更新

根据go-nuts irc上mac01021的建议,我已经添加了:

#pragma GCC diagnostic ignored "-Wdeprecated-declarations"  

这样做可以消除过时警告,但仍无法针对OS X中包含的iODBC进行构建。
将上述行替换为:
#cgo darwin CFLAGS: -I/opt/local/include 

现在mgodbc已经构建完成(使用已安装的unixODBC)
尽管在导入时会出现一个小的段错误 =(


ODBC

我遇到了构建错误:

# code.google.com/p/odbc/api
api/api.go:13: undefined: SQLSMALLINT  
api/api.go:14: undefined: SQLUSMALLINT  
api/api.go:15: undefined: SQLUSMALLINT  
api/api.go:19: undefined: SQLSMALLINT  
api/api.go:20: undefined: SQLUSMALLINT  
api/api.go:21: undefined: SQLUSMALLINT  
api/api.go:22: undefined: SQLUSMALLINT  
api/api.go:23: undefined: SQLUSMALLINT  
api/api.go:24: undefined: SQLUSMALLINT  
api/api.go:25: undefined: SQLUINTEGER  
api/api.go:25: too many errors  

更新

感谢@alex提供信息。我已经使用以下内容修改了api_unix.go

// Copyright 2012 The Go Authors. All rights reserved.  
// Use of this source code is governed by a BSD-style  
// license that can be found in the LICENSE file.  

// +build linux darwin  
// +build cgo  

package api  

// #cgo linux LDFLAGS: -lodbc  
// #cgo darwin LDFLAGS: -lodbc  
// #cgo darwin CFLAGS: -I /opt/local/include  
// #include <sql.h>  
// #include <sqlext.h>  
import "C"  

在OS X中包含的iODBC有一些被列为弃用的内容(我过去使用unixODBC的运气更好)

我已经将-I /opt/local/include添加到CFLAGS中,希望指向unixODBC头文件,而不是由Apple提供的那些(其中包含弃用警告等)

运行# go build -x会给我:

WORK=/var/folders/z2/k9vxn7gn6395vb3y2qc7_1040000gn/T/go-build784364461  
mkdir -p $WORK/code.google.com/p/odbc/api/_obj/  
mkdir -p $WORK/code.google.com/p/odbc/  
cd /Users/jr/Development/go/src/code.google.com/p/odbc/api  
/usr/local/go/pkg/tool/darwin_amd64/cgo -objdir $WORK/code.google.com/p/odbc/api/_obj/ -- -I /opt/local/include -I $WORK/code.google.com/p/odbc/api/_obj/ api_unix.go  
/usr/local/go/pkg/tool/darwin_amd64/6c -F -V -w -I $WORK/code.google.com/p/odbc/api/_obj/ -I /usr/local/go/pkg/darwin_amd64 -o $WORK/code.google.com/p/odbc/api/_obj/_cgo_defun.6 -D GOOS_darwin -D GOARCH_amd64 $WORK/code.google.com/p/odbc/api/_obj/_cgo_defun.c  
gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -print-libgcc-file-name
gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -I /opt/local/include -I $WORK/code.google.com/p/odbc/api/_obj/ -o $WORK/code.google.com/p/odbc/api/_obj/_cgo_main.o -c $WORK/code.google.com/p/odbc/api/_obj/_cgo_main.c  
gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -I /opt/local/include -I $WORK/code.google.com/p/odbc/api/_obj/ -o $WORK/code.google.com/p/odbc/api/_obj/_cgo_export.o -c $WORK/code.google.com/p/odbc/api/_obj/_cgo_export.c  
gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -I /opt/local/include -I $WORK/code.google.com/p/odbc/api/_obj/ -o $WORK/code.google.com/p/odbc/api/_obj/api_unix.cgo2.o -c $WORK/code.google.com/p/odbc/api/_obj/api_unix.cgo2.c  
gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -o $WORK/code.google.com/p/odbc/api/_obj/_cgo_.o $WORK/code.google.com/p/odbc/api/_obj/_cgo_main.o $WORK/code.google.com/p/odbc/api/_obj/_cgo_export.o $WORK/code.google.com/p/odbc/api/_obj/api_unix.cgo2.o -lodbc
/usr/local/go/pkg/tool/darwin_amd64/cgo -objdir $WORK/code.google.com/p/odbc/api/_obj/ -dynimport $WORK/code.google.com/p/odbc/api/_obj/_cgo_.o -dynout $WORK/code.google.com/p/odbc/api/_obj/_cgo_import.c  
/usr/local/go/pkg/tool/darwin_amd64/6c -F -V -w -I $WORK/code.google.com/p/odbc/api/_obj/ -I /usr/local/go/pkg/darwin_amd64 -o $WORK/code.google.com/p/odbc/api/_obj/_cgo_import.6 -D GOOS_darwin -D GOARCH_amd64 $WORK/code.google.com/p/odbc/api/_obj/_cgo_import.c  
gcc -I . -g -O2 -fPIC -m64 -pthread -fno-common -o $WORK/code.google.com/p/odbc/api/_obj/_all.o $WORK/code.google.com/p/odbc/api/_obj/_cgo_export.o $WORK/code.google.com/p/odbc/api/_obj/api_unix.cgo2.o -Wl,-r -nostdlib /usr/llvm-gcc-4.2/bin/../lib/gcc/i686-apple-darwin11/4.2.1/x86_64/libgcc.a  
/usr/local/go/pkg/tool/darwin_amd64/6g -o $WORK/code.google.com/p/odbc/api/_obj/_go_.6 -p code.google.com/p/odbc/api -D _/Users/jr/Development/go/src/code.google.com/p/odbc/api -I $WORK ./api.go $WORK/code.google.com/p/odbc/api/_obj/_cgo_gotypes.go $WORK/code.google.com/p/odbc/api/_obj/api_unix.cgo1.go  
/usr/local/go/pkg/tool/darwin_amd64/pack grcP $WORK $WORK/code.google.com/p/odbc/api.a $WORK/code.google.com/p/odbc/api/_obj/_go_.6 $WORK/code.google.com/p/odbc/api/_obj/_cgo_import.6 $WORK/code.google.com/p/odbc/api/_obj/_cgo_defun.6 $WORK/code.google.com/p/odbc/api/_obj/_all.o  
mkdir -p $WORK/code.google.com/p/odbc/_obj/  
mkdir -p $WORK/code.google.com/p/  
cd /Users/jr/Development/go/src/code.google.com/p/odbc  
/usr/local/go/pkg/tool/darwin_amd64/6g -o $WORK/code.google.com/p/odbc/_obj/_go_.6 -p code.google.com/p/odbc -complete -D _/Users/jr/Development/go/src/code.google.com/p/odbc -I $WORK -I /Users/jr/Development/go/pkg/darwin_amd64 ./column.go ./conn.go ./driver.go ./error.go ./handle.go ./odbcstmt.go ./param.go ./result.go ./rows.go ./stats.go ./stmt.go ./tx.go  
# code.google.com/p/odbc  
./column.go:22: undefined: api.SQLGetData  
./column.go:28: undefined: api.SQLBindCol  
./column.go:47: undefined: api.SQLDescribeCol  
./conn.go:20: undefined: api.SQLAllocHandle  
./conn.go:28: undefined: api.SQLDriverConnect  
./conn.go:39: undefined: api.SQLDisconnect  
./driver.go:26: undefined: api.SQLAllocHandle  
./driver.go:34: undefined: api.SQLSetEnvAttr  
./driver.go:43: undefined: api.SQLSetEnvAttr  
./driver.go:50: undefined: api.SQLSetEnvAttr  
./driver.go:50: too many errors  

看起来头文件路径被正确地传递了?
但似乎链接还不太正确?

对于SQLGetData,我在api.go中的//sys SQLGetData...注释中确实看到与/opt/local/include/sql.h中匹配的定义。


更新

顶部提到的这个库:

brainman http://code.google.com/p/odbc/

现在可在OSX上作为go-gettable软件包使用。甚至有文档介绍如何开始使用odbc/tds部分。


我还使用已安装的unixODBC/FreeTDS库构建了pyODBC,一切都连接正常(只是为了排除其他可能性)。 - Justin
更新iODBC安装似乎比转向从未被苹果认可的驱动程序管理器更有意义...这些头文件中也没有弃用标记。 - TallTed
1个回答

3
在 Windows 上:
>go version
go version devel +edd229b63fa4 Wed Jun 26 11:36:18 2013 -0700 windows/amd64
>go get -v code.google.com/p/odbc
code.google.com/p/odbc (download)
code.google.com/p/odbc/api
code.google.com/p/odbc
>go get -v bitbucket.org/miquella/mgodbc
bitbucket.org/miquella/mgodbc (download)
bitbucket.org/miquella/mgodbc
>

在Linux上:

$ go version
go version devel +65e2aba21abe Wed Jun 26 13:14:11 2013 -0700 linux/amd64
$ sudo apt-get install unixodbc unixodbc-dev
Reading package lists... Done
Building dependency tree       
Reading state information... Done
unixodbc is already the newest version.
unixodbc-dev is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 10 not upgraded.
$ go get -v code.google.com/p/odbc
code.google.com/p/odbc (download)
code.google.com/p/odbc/api
code.google.com/p/odbc
$ go get -v bitbucket.org/miquella/mgodbc
bitbucket.org/miquella/mgodbc (download)
bitbucket.org/miquella/mgodbc
$ 

在Darwin上,您似乎遇到了SQL头文件的问题。
/usr/include/sql.h
/usr/include/sqlext.h
/usr/include/sqltypes.h
/usr/include/sqlucode.h

请联系odbc软件包的作者报告这些问题。

更新:

当您向我们汇报错误时,

mgodbc.go:180: cannot convert &state[0] (type *uint16) to type *_Ctype_SQLWCHAR  

您并没有告诉我们_Ctype_SQLWCHAR的类型。我们只能猜测!我的猜测是它应该像这样:

package main

func main() {
    type _Ctype_ushort uint16
    type _Ctype_WCHAR _Ctype_ushort
    type _Ctype_SQLWCHAR _Ctype_WCHAR
    var state [6]uint16
    // (*C.SQLWCHAR)(&state[0])
    _ = (*_Ctype_SQLWCHAR)(&state[0])
}

没有错误地编译。

更新:

采用系统化的方法解决问题。

阅读有关Go构建约束的内容: Build Constraints, Package build.

阅读code.google.com/p/odbc/api中的文件。

code.google.com/p/odbc/api的文件中搜索。

$ grep -r 'linux' *
api_unix.go:// +build linux
api_unix.go:// #cgo linux LDFLAGS: -lodbc
Makefile:   GOOS=linux ./mksyscall_unix.pl $^ \
mksyscall_unix.pl:// +build linux
mksyscall_unix.pl:// #cgo linux LDFLAGS: -lodbc
zapi_unix.go:// +build linux
zapi_unix.go:// #cgo linux LDFLAGS: -lodbc
$ 

显然,阅读过api_unix.gozapi_unix.gomksyscall_unix.plMakefile文件后,当修改api_unix.go文件时,也应该修改zapi_unix.go文件。

你可能没有这样做。因此,在zapi_unix.go构建约束中没有包括darwin。你显示为未定义的api包名称在zapi_unix.go中有定义。

api.SQLGetData
api.SQLBindCol  
api.SQLDescribeCol  
api.SQLAllocHandle  
api.SQLDriverConnect  
api.SQLDisconnect  
api.SQLAllocHandle  
api.SQLSetEnvAttr   

1
谢谢@peterSO。我成功地在一个开发CentOS盒子上构建/安装了这个。苹果坚持默认包含iODBC,叹息。我已经安装了unixODBC,但是go build正引用默认iODBC安装的头文件,而不是unixODBC提供的头文件。所以我只需要在安装期间让go查找那里,我认为它应该可以工作=) - Justin
1
Justin,code.google.com/p/odbc在darwin上不受支持,因为我没有darwin。但是,如果您将darwin添加到像https://code.google.com/p/odbc/source/browse/api/api_unix.go#5这样的行中,它可能会对您起作用。 - alex
1
@alex:你应该在你的odbc驱动项目网站上说明支持哪些操作系统。 - peterSO
1
@Justin:我已经修改了我的答案,以反映您最近对问题的更新。 - peterSO
1
谢谢@peterSO,看起来我只是错过了之前的修改,在其他文件中添加了api_unix.go,哎呀!包现在可以构建了!虽然我仍然会得到与mgodbc相同的段错误,所以我还有一些工作要做。感谢您让我走上了正确的道路=) - Justin
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接