移植freetds连接sql server教程
一、 freetds介绍
最近工作中项目需要嵌入式linux连接sql server数据库的要求,之前对sql server完全不了解,所以加强学习,经过半年的断断续续的开发学习,下面将自己你的经验总结一下。
Freetds是一个开源的C程序库,是TDS(表列数据流)协议的再次实现,它可以被利用在Sybase的db-lib或者ct-lib库。它也包含一个ODBC库。允许许多开源的应用软件比如Perl和PHP(或者你自己的c或C++程序)去连接Sybase或Microsoft SQL服务器。
二、 移植
Freetds源码可以到官网上下载http://www.freetds.org/。最新的稳定版本为freetds-0.91。获取源码就开始移植了。
1、将代码拷贝到虚拟机中的ubuntu中,我的开发环境是Ubuntu 12.04+arm-linux-gcc3.4.1。解压当前代码:tar zxvf freetds-stable.tgz。
2、解压完成后进入freetds-0.91这个目录,进行配置./configure --host=arm-linux --prefix=/usr/local/freetds --with-tdsver=7.1 --enable-msdblib --disable-libiconv。
选项介绍:
--prefix是freetds的安装路径
--with-tdsver是freetds版本,此处选7.1
--enable-msdblib是打开访问microsoft sql功能
--disable-libconv是关闭编码转换。
配置完成后,可以make,make install了,此处需注意make install时会出现libtool之类的错误,是因为arm-linux-gcc环境变量只在普通用户中,此时需要sudo make install。解决方法是进入root模式下,终端下export PATH=$PATH:跟你的arm-linux-gcc路径,之后make install。将freetds文件夹拷入到根文件系统中的/usr/local目录下。
3、通过nfs挂载文件系统,终端下输入 tsql –C,当出现下面提示时,就表示移植成功了。
在终端下输入:tsql –H 192.168.1.56 –U sa –p 1433
提示输入密码后,输入数据库查询语句,具体操作如图,
-H代表服务器IP,-U代表数据库用户名,-p代表数据库连接端口号
三、 编写C程序连接SQL 2008
测试程序如下:
#include
#include
#include
#include
char szUsername[32] = "sa"; //用户名
char szPassword[32] = "sa"; //密码
char szDBName[32] = "TDS_Test";//数据库名
char szServer[32] ="192.168.1.56:1433";//数据库服务器:端口
static LOGINREC *loginrec;//包含登陆信息
static DBPROCESS *dbprocess;//句柄,包含很多信息,具体看freetds文档
int main ()
{
char buf[255] = {0};
int result_code;
int row_code;
char *ErrMsg=NULL;
int num = 0;
char name[50] = {0};
dbinit();
loginrec = dblogin();
DBSETLUSER(loginrec,szUsername);
DBSETLPWD(loginrec,szPassword);
dbsetlogintime(1);
dbprocess= dbopen(loginrec,szServer);
if(dbprocess == FAIL)
{
printf("链接数据库失败\n");
return 0;
}
if(dbuse(dbprocess,szDBName)== FAIL)
{
printf("连接数据库失败\n");
}
printf("connect sql server success\n");
sprintf(buf,"select Number,Name from Student_Info");
printf(buf);
printf("\n");
dbcmd(dbprocess,buf);
if(dbsqlexec(dbprocess)== FAIL)
{
printf("dbsqlexecerror \n");
dbclose(dbprocess);
return 0;
}
while((result_code= dbresults(dbprocess) != NO_MORE_RESULTS))
{
if(result_code== SUCCEED)
{
dbbind(dbprocess,1, INTBIND, (DBINT)0, (BYTE*)&num);
dbbind(dbprocess,2, CHARBIND, (DBCHAR)0, name);
}
while((row_code= dbnextrow(dbprocess)) != NO_MORE_ROWS)
{
if(row_code= REG_ROW)//此处需要看freetds的官网文档,具体了解dbnextrow的返回值,此处不做过多解释
{
printf("numis %d\n",num);
printf("nameis %s\n",name);
}
else
{
return 0;
}
}
}
dbclose(dbprocess);
return 0;
}
终端下输入:
export LD_LIBRARY_PATH=/usr/local/freetds/lib/:$LD_LIBRARY_PATH
编译:arm-linux-gcc freetds_test.c -lsybdb -L /usr/local/freetds/lib/
将执行程序拷入文件系统中运行,结果如下:
数据库需自己添加,此处不再过多说明。
注意项:数据库中包含中文的字段类型必须是nvarchar或nchar,freetds配置文件为usr/local/etc/freetds.conf,需指定字符集为utf8,这样才能显示中文,否则会显示乱码。
配置文件如下:
# $Id:freetds.conf,v 1.12 2007/12/25 06:02:36 jklowden Exp $
#
# This file is installed by FreeTDS if no file by thesame
# name is found in the installation directory.
#
# For information about the layout of this file andits settings,
# see the freetds.conf manpage "manfreetds.conf".
# Global settings are overridden by those in adatabase
# server specific section
[global]
# TDSprotocol version
; tds version =4.2
tds version = 7.1//自己添加
# Whether towrite a TDSDUMP file for diagnostic purposes
# (settingthis to /tmp is insecure on a multi-user system)
; dump file =/tmp/freetds.log//调试信息,取消注释后可以查看
; debug flags =0xffff
# Command andconnection timeouts
; timeout = 10
; connecttimeout = 10
client charset = utf8//自己添加
# If you getout-of-memory errors, it may mean that your client
# is tryingto allocate a huge buffer for a TEXT field.
# Try setting'text size' to a more reasonable limit
text size =64512
# A typical Sybase server
[egServer50]
host =symachine.domain.com
port = 5000
tds version =5.0
# A typical Microsoft server
[egServer70]
host =ntmachine.domain.com
port = 1433
tds version = 7.0
四、 SQL SERVER2008开启远程连接方法
具体操作参考如下地址:
http://wenku.baidu.com/link?url=A2ZcL_SrbaIWQQNiFOV65-mGUKwZRKfnwFc5EVrJozWHVWxwD9Pw-1xZPmAtNXhBdMkguD3XHd4hAyfg8uJMVxKv6VsVuba6Vxm3gouANom
五、varchar和nvarchar的区别
varchar在SQL Server中是采用单字节来存储数据的,nvarchar是使用Unico来存储数据的.中文字符存储到SQL Server中会保存为两个字节(一般采用Unico编码),英文字符保存到数据库中,如果字段的类型为varchar,则只会占用一个字节,而如果字段 的类型为nvarchar,则会占用两个字节.
正常情况下,我们使用varchar也可以存储中文字符,但是如果遇到操作系统是英文操作系统并且对中文字体的支持不全面时, 在SQL Server存储中文字符为varchar就会出现乱码(显示为??).而且正常情况下,主机都会支持中文的环境,所以如果使用varchar来存储数 据,在开发阶段是发现不了的.多数情况下,在布署的时候也不会有问题.
但是!如果布署的主机是英文操作系统,并且不支持中文环境,那问 题就出来了.所有的varchar字段在存储中文的时候都会变成乱码(显示为??).而且一般情况下你不会知道这是因为你采用了错误的数据类型来存储所造 成的,你会试着去装中文字体,试着去设置操作系统的语言环境...这些都不能解决问题,唯一能解决问题的是把数据库字段的类型个性为nvarchar(或 者nchar).对项目管理比较熟悉的朋友应该都知道,到布署阶段再来修改数据库是一个很恐怖的事情.
使用nvarchar的另一个非常好处就是在判断字符串的时候可以不需要考虑中英文两种字符的差别.
当然,使用nvarchar存储英文字符会增大一倍的存储空间.但是在存储代价已经很低廉的情况下,优先考虑兼容性会给你带来更多好处的.
所以在Design的时候应该尽量使用nvarchar来存储数据.只有在你确保该字段不会保存中文的时候,才采用varchar来存储.
1、CHAR。CHAR存储定长数据很方便,CHAR字段上的索引效率级高,比如定义char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间。
2、VARCHAR。存储变长数据,但存储效率没有CHAR高。如果一个字段可能的值是不固定长度的,我们只知道它不可能超过10个字符,把它定义为 VARCHAR(10)是最合算的。VARCHAR类型的实际长度是它的值的实际长度+1。为什么“+1”呢?这一个字节用于保存实际使用了多大的长度。
从空间上考虑,用varchar合适;从效率上考虑,用char合适,关键是根据实际情况找到权衡点。
3、TEXT。text存储可变长度的非Unicode数据,最大长度为2^31-1(2,147,483,647)个字符。
4、NCHAR、NVARCHAR、NTEXT。这三种从名字上看比前面三种多了个“N”。它表示存储的是Unicode数据类型的字符。我们知道字符中,英文字符只需要一个字节存储就足够了,但汉字众多,需要两个字节存储,英文与汉字同时存在时容易造成混乱,Unicode字符集就是为了解决字符集这种不兼容的问题而产生的,它所有的字符都用两个字节表示,即英文字符也是用两个字节表示。nchar、nvarchar的长度是在1到4000之间。和char、varchar比较起来,nchar、nvarchar则最多存储4000个字符,不论是英文还是汉字;而char、varchar最多能存储8000个英文,4000个汉字。可以看出使用nchar、nvarchar数据类型时不用担心输入的字符是英文还是汉字,较为方便,但在存储英文时数量上有些损失