ms sqlserver是微软出品,自然没有unix版本,对于c++来说,客户端也很少,最著名的是freetds,他有两种访问模式,一种就是ODBC的方式,还有一种是直连的方式。对于大部分开发者来说,减少配置,是一致的看法。所以本文介绍freetds直连sqlserver的方法。
freetds提供了两个库,一是libsybdb,另一个是libct,两者都可以完成。但是如果直接使用freetds API,会很麻烦,网上也有对这两者的包装,但是都有bug
先介绍libct的包装tdspp,这个是老外写的,比较专业,但是官网上的版本有bug,这里主要是针对访问高版本的sql server会有问题,从github上下载的代码修复了这个问题。
但是如果直接使用会有中文乱码问题,解决方法是在你的应用程序最前面加上setlocale(LC_ALL, ""),就搞定了,为什么要这么做,是因为我看了tsql.c的代码,他没问题,我也就这样做了,也好了,我尝试了很多设置编码的方法,例如很专业的
cs_locale(ctx, CS_SET, locl, CS_SYB_LANG_CHARSET, (CS_VOID*)"en_US.UTF-8", CS_NULLTERM, (CS_INT*)NULL)
ct_con_props(conn, CS_SET, CS_LOC_PROP, (CS_VOID*)locl, CS_NULLTERM, (CS_INT*)NULL) != CS_SUCCEED)
但是跟代码发现这个设置怎么是设置server端的编码,可能另有他用。
另一个库libsybdb的封装是我在csdn博客上看到的,链接是http://blog.csdn.net/qwidget/article/details/6444829,我不知道是不是他本人写的,封装的挺好,但是有问题,问题还很隐蔽,是内存double free或者内存崩溃,但是看封装的好像头头是道,最后我对着官网的例子(官网也就提供了这个库的例子,没有ct的例子),发现dbbind函数,这里参数传错了,改成
dbbind(dbprocess, i+1, NTBSTRINGBIND, pBufSize[i], (BYTE*)(currentRow->getField(i)))
万事大吉,它的中文问题解决很easy,因为他直接提供了DBSETLCHARSET接口。
ODBC待续