最近一个项目中使用FreeTDS实现Linux中请求MS SQL Server。
过程中遇到过一些问题,比较简单,却花费了一些时间。
应同事建议,这里结合网上大家的看法及自己的实践做个简单总结。
首先是FreeTDS的安装,网上有很多介绍,具体步骤如下:
1. 下载源码包
可以使用下面链接,也可以去官网上下载,目前最新的是0.91版本
2. 解压后编译安装
[vnzn@localhost freetds-0.91]$ make distclean
[vnzn@localhost freetds-0.91]$ ./configure --prefix=/usr/local/freetds --with-tdsver=7.1 --enable-msdblib
[vnzn@localhost freetds-0.91]$ make
[vnzn@localhost freetds-0.91]$ make install
--with-tdsver=7.1的意思是指定freetds动态库及utility测试工具的默认TDS版本。
其实这个真的不重要,如果不懂得怎么选择的话,可以直接配置为7.1,或者在使用的时候具体指定。
下面是关于如何选择这个版本号。
再强调一下,不论这里选择什么版本,具体使用的时候都可以临时指定,这里选择一个跟你服务器对应的版本,只是让后面使用的时候更方便:
根据help里:
[vnzn@localhost freetds-0.91]$ ./configure --help
--with-tdsver=VERSION TDS protocol version (4.2/4.6/5.0/7.0/7.1) [5.0]
可见FreeTDS支持TDS版本最高为7.1,默认为5.0。网上大部分文章都选择8.0,这部分的说明没有找到, 但是根据configure文件里的内容:
16513 # Check whether --with-tdsver was given.
16514 if test "${with_tdsver+set}" = set; then :
16515 withval=$with_tdsver;
16516 fi
16517
16518 if test "$with_tdsver" = "4.2"; then
16519
16520 $as_echo "#define TDS42 1" >>confdefs.h
16521
16522 elif test "$with_tdsver" = "4.6"; then
16523
16524 $as_echo "#define TDS46 1" >>confdefs.h
16525
16526 elif test "$with_tdsver" = "7.0"; then
16527
16528 $as_echo "#define TDS70 1" >>confdefs.h
16529
16530 elif test "$with_tdsver" = "7.1"; then
16531
16532 $as_echo "#define TDS71 1" >>confdefs.h
16533
16534 else
16535
16536 $as_echo "#define TDS50 1" >>confdefs.h
16537
16538 fi
发现如果指定为8.0或者7.2等任何FreeTDS不支持的版本, 安装的时候均指定默认为5.0版本。
我猜测网上使用8.0是由于之前的FreeTDS中对TDS版本的定义与现在不同,具体可以参考http://www.freetds.org/userguide/tdshistory.htm 中的NOTE [1]。
另外,对于TDS版本的选择可以参考http://www.freetds.org/userguide/choosingtdsprotocol.htm 。
3. 配置系统动态链接库搜索路径
这个步骤用于应用程序调用动态库的时候可以找到相应的位置。
其实如果搜索不到相应的动态链接库,应用运行时会提示error while loading shared libraries: xxx.so.x
但是我在UBUNTU 12.04 X86 64位版本服务器上测试的时候没有任何关于缺少库的提示,只是从FreeTDS的异常中得到Unexpected EOF from the server的出错信息,与TDS版本不匹配时提示的信息相同,因此这里介绍一下如何配置动态链接库的路径:
在/etc/ld.so.conf.d/中新建freetds.conf内容为/usr/local/freetds/lib/
保存后执行指令:
[vnzn@localhost ld.so.conf.d]$ ldconfig
至此FreeTDS安装完成。
然后对所安装的FreeTDS进行测试:
1. 使用安装时指定的默认TDS版本测试
[vnzn@localhost ~]$ /usr/local/freetds/bin/tsql -H serverip -p port -U username -P password
2. 临时指定TDS版本
[vnzn@localhost ~]$ TDSVER=7.1 /usr/local/freetds/bin/tsql -H serverip -p port -U username -P password
链接到服务器后有如下提示:
1. [vnzn@localhost ~]$ TDSVER=7.1 /usr/local/freetds/bin/tsql -H serverip -p port -U username -P password
locale is "en_US.UTF-8"
locale charset is "UTF-8"
using default charset "UTF-8"
1>
2> bye
测试完成。
FreeTDS C语言编程:
FreeTDS动态链接库在C中的调用网上可以搜索到例程,强调一个宏和两个函数:
1. 设置TDS版本宏
使用这个宏可以临时指定TDS的版本
1172 #define DBSETLVERSION(login, version) dbsetlversion((login), (version))
2. 设置出错回调函数和信息回调函数
其中出错回调函数对调试帮助比较大
441 typedef int (*EHANDLEFUNC) (DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr);
442
443 typedef int (*MHANDLEFUNC) (DBPROCESS * dbproc, DBINT msgno, int msgstate, int severity, char *msgtext, char *srvname,
444 char *proc, int line);
...
666 EHANDLEFUNC dberrhandle(EHANDLEFUNC handler);
...
725 MHANDLEFUNC dbmsghandle(MHANDLEFUNC handler);
具体可用资源可以参考/usr/local/freetds/include/sybdb.h
问题解决方案:
OS: error while loading shared libraries: xxx.so.x 使用上述配置搜索路径步骤解决
FreeTDS: Unexpected EOF from the server
如果使用utility测试时出现这个错误,则指定TDS版本号与MS SQL Server TDS版本号对应可以解决;
如果utility测试可以通过,C编程时错误回调函数提示这个错误,则需要使用上述配置搜索路径步骤解决。
上述在UBUNTU 12.04 x86 64位及CentOS release 6.2 (Final)测试过,文章落笔草草,理解程度有限,任何错误请不吝赐教。
参考链接:
Linux C语言通过freetds链接sqlserver数据库乱码问题解决办法 http://hi.baidu.com/weichenvnzn/item/a82da9376b20e462033edc7e
linux下freeTDS的安装 http://blog.csdn.net/dlutxie/article/details/6851429
error while loading shared libraries: xxx.so.x"解决办法 http://hi.baidu.com/weichenvnzn/item/94141a7864542001d7a89c01
FreeTDS官方网站 http://www.freetds.org/
FreeTDSFTP服务器
FreeTDS帮助文档 http://www.freetds.org/userguide/