Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go 1.1.1 and ODBC with MSSQL

Tags:

go

odbc

Currently have FreeTDS 0.92.4 / unixODBC 2.3.1 up and running, connecting with a MSSQL server and able to execute queries etc.

I've found this list of ODBC implementations for Go, and have tried the two in bold:

  • BenoyRNair https://github.com/BenoyRNair/godbc/
  • Wei guangjing https://github.com/weigj/go-odbc
  • Mark Severson https://bitbucket.org/miquella/mgodbc
  • Luke Mauldin https://github.com/LukeMauldin/lodbc
  • Robert Johnstone https://bitbucket.org/rj/odbc3-go/
  • brainman http://code.google.com/p/odbc/

mgodbc

I'm getting a bunch of deprecation warnings (looking at the headers they're deprecated for OSX 10.8 and later):

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)

Update

Following a suggestion from mac01021, from go-nuts irc, I've added

#pragma GCC diagnostic ignored "-Wdeprecated-declarations"  

This gets rid of the deprecation warnings, but still doesn't build against the included iODBC of OS X

Replacing the above line with:

#cgo darwin CFLAGS: -I/opt/local/include 

and voila, mgodbc builds now (using the installed unixODBC)
although now a nice little segfault occurs upon import =(


odbc

I'm getting build errors:

# 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  

Update

Thanks @alex for the cgo info. I've modified api_unix.go with the below

// 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"  

The iODBC included with OS X has some things that are listed as deprecated (and I've had better luck with unixODBC in the past)

I've added the -I /opt/local/include to the CFLAGS to, hopefully, point to the unixODBC headers, and not the ones included by Apple (which have the deprecation warnings etc.)

Running # go build -x gives me:

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  

It looks like the header path include is being passed correctly?
But still looks like things are not quite linking correctly?

for SQLGetData I do see a matching definition from the //sys SQLGetData... comment from api.go within /opt/local/include/sql.h


UPDATE

The library mentioned at the top:

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

Now works as a go-gettable package on OSX. There's even documentation to get you started with the odbc/tds portions.

like image 344
Justin Avatar asked Jun 26 '13 19:06

Justin


People also ask

Which ODBC driver should I use for SQL Server?

Microsoft ODBC Driver for SQL Server (MSODBCSQL) Driver history for Microsoft SQL Server recommends this driver in preference to "SQL Server" and "SQL Server Native Client" for ODBC.

How do I get ODBC driver 17 for SQL Server?

To download the Microsoft ODBC Driver 17 for SQL Server, please go to the documentation page at https://aka.ms/downloadmsodbcsql. This page is no longer maintained. To download the Microsoft ODBC Driver 17 for SQL Server, please go to the documentation page at https://aka.ms/downloadmsodbcsql.

What is ODBC driver 13 SQL Server?

The Microsoft ODBC Driver for SQL Server provides native connectivity from Windows + Linux to Microsoft SQL Server and Microsoft Azure SQL Database. Details. Note: There are multiple files available for this download. Once you click on the "Download" button, you will be prompted to select the files you need.


Video Answer


1 Answers

On 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
>

On 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
$ 

On Darwin, you seem to have issues with SQL header files.

/usr/include/sql.h
/usr/include/sqlext.h
/usr/include/sqltypes.h
/usr/include/sqlucode.h

Contact the odbc package authors to report these problems.

UPDATE:

When you tell us about the error

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

you don't tell us what the type of _Ctype_SQLWCHAR is. We can only guess! My guess would be that it should look like this

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])
}

which compiles with no errors.

UPDATE:

Use a systematic approach to problem solving.

Read about Go build contraints: Build Constraints, Package build.

Read the files in code.google.com/p/odbc/api.

Grep the files in 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
$ 

Clearly, after reading the api_unix.go, zapi_unix.go, mksyscall_unix.pl, and Makefile files, when the api_unix.go file is modified, the zapi_unix.go file should be modified too.

You probably didn't do that. Therefore, darwin is not included in the zapi_unix.go build constraints. The package api names that you show as undefined are defined in zapi_unix.go.

api.SQLGetData
api.SQLBindCol  
api.SQLDescribeCol  
api.SQLAllocHandle  
api.SQLDriverConnect  
api.SQLDisconnect  
api.SQLAllocHandle  
api.SQLSetEnvAttr   
like image 98
peterSO Avatar answered Nov 15 '22 05:11

peterSO