本博客转自 http://blog.csdn.net/pinkbean/article/details/64439759
1.freetds是什么? freetds其实就是个软件而且是一款开源软件,而且这个软件支持相当多的系统,比如Linux, Unix, Windows, 当你在Linux上安装了这个软件并且配置了这个软甲的环境变量,你就可以在shell上使用相关的命令来直接操作这个软件来实现我们想要的功能, 同时我们在安装完freetds软件的时候,
freetds软件的发行商也提供给我们了相关的函数库和头文件,使得我们在自己开发的程序中也可以调用freetds的相关接口来实现我们想要的功能.2.为什么我们要使用freetds, freetds的功能是什么? 我们都知道,向我们在Linux上使用的数据库一般都为MySQL, MySQL是一款开源数据库,当你在Linux上安装MySQL的时候, MySQL会提供给你连接它的方式, 但是当我们连接出了MySQL以外的一些比较特殊的数据库是, 比如Windows上的不开源的SQLServer时怎么办? 微软好像也没有针对Linux开放出API,
因为这个软件就是针对于Windows设计的, 这个时候我们就可以使用三方软件freetds来完成对SQLServer的连接和操作, 而且freetds不仅支持SQLServer而且还支持Sybase databases(塞班数据库).
3.freetds的相关函数介绍
一下相关函数接口用于freetds v0.91
**注意:我们在要使用freetds进行开发时候一定要引用freetds的相关头文件sybfront.h和sybdb.h,
同时我们在编写Makefile的使用也要连接freetds的相关函数库-lsybdb, 否则头文件是找不到函数的原型的**注意:SQLServer的默认编码可能是GBK, 而我们在Linux下编程使用的默认编码集一般为UTF-8,
当我们在Linux程序中使用SQL语句操作SQLServer时候特别是我们的SQL语句中有中文的时候, SQL语句从UTF-8转变为GBK,会产生乱码, 使得你永远都无法将SQL语句执行成功, 而且程序也不会给出明显的错误提示
Linux系统中使用的默认编码,可以在 /etc/sysconfig/i18n 文件中查看
**注意:我这边再介绍几个变量: <1>RETCODE:我们在头文件sybdb.h头文件中发现了他的先关定义, 其实RETCODE就是int, 原始代码是:typedef int RETCODE <2>SUCCEED:这个值也是int, 他的定义也位于sybdb.h上, 原始代码为:#define SUCCEED 1 <3>FAIL:这个值也是int, 他的定义也位于sybdb.h上, 原始代码为:#define FAIL 0(1)dbinit()函数原型: #include #include RETCODE dbinit(void);返回值:RETCODE:<1>成功时返回SUCCEED <2>失败时返回FAIL参数:无函数作用:在你调用freetds的其他的函数的时候一定要先调用这个函数, 这个函数的作用就是进行一些初始化工作,
好比如为结构体分配空间, 还有读取你Linux上的一些配置文件, 来确定日期格式和其他信息(2)dblogin()函数原型: #include #include LOGINREC* dblogin(void)返回值:<1>这个函数失败时返回NULL <2>成功时返回一个LOGINREC指针, 这是一个结构体, 这个结构体中包含了连接数据库的相关参数 LOGINREC结构体中的内容: char* client_charset 客户端字符编码集
char* client_hostname 连接数据库的IP char*
username 连接数据库的用户名称
char* password 连接数据库时使用的密码
int query_timeout 发送请求命令时的超时时间
int connect_timeout 连接数据库的超时时间
参数:无函数作用:创建一个LOGINRES指针,并且返回它(3)dbsetlname()函数原型: #include #include RETCODE dbsetlname(LOGINREC* login, const char* value, int which)返回值:<1>成功时返回SUCCEED <2>失败时返回FAIL参数:<1>LOGINREC*:一个LOGINREC指针 <2>value:我们要设置的选项的值 <3>which:我们要设置的选项, 好比如: DBSETUSER(int类型)....函数作用:设置LOGINREC中的相关的选项的值(4)DBSETLUSER()函数原型: #include #include DBSETLUSER(LOGINREC* login, char* UserName)返回值:RETCODE:<1>函数执行成功时返回SUCCEED <2>函数执行失败时返回FAIL参数:<1>LOGINREC*:一个LOGINREC指针 <2>UserName:登录数据库的用户的名称函数作用:向LOGINREC结构体中设置登录用户的名称函数介绍:其实这个函数就是宏定义函数, 在头文件sybdb.h是这么定义的:#define DBSETLUSER(x,y)
dbsetlname((x), (y), DBSETUSER)(5)DBSETLPWD()函数原型: #include #include DBSETLPWD(LOGINREC* login, char* PassWord)返回值:RETCODE:<1>函数执行成功时返回SUCCEED <2>函数执行失败时返回FAIL参数:<1>LOGINREC*:一个LOGINREC指针 <2>PassWord:登录数据库的用户的密码函数作用:向LOGINREC结构体中设置登录用户的密码函数介绍:其实这个函数就是宏定义函数, 在头文件sybdb.h是这么定义的:#define DBSETLPWD(x,y)
dbsetlname((x), (y), DBSETPWD)(6)dbopen()函数原型: #include #include DBPROCESS* dbopen(LOGINREC* login, const char* server)返回值:<1>成功时返回DBPROCESS*, 一个成功连接到数据库的句柄 <2>失败时返回NULL参数:<1>LOGINREC*:一个LOGINREC指针, 指针中一定要保存了连接使用户的用户名称, 以及用户的密码 <2>server:要连接数据库的IP地址函数作用:连接到数据库, 并且返回成功连接的句柄(7)dbuse()函数原型: #include #include RETCODE dbuse(DBPROCESS* dbproc, const char* name)返回值:<1>成功时返回SUCCEED <2>失败时返回FAIL参数 :<1>dbproc:已经连接到数据库的连接句柄 <2>name:要使用的数据库的名字函数作用:使用SQLServer中的具体的某个数据库, 相当于在数据库中执行use XXXXdatabase命令,
这个函数一定要在dbopen()之后运行(8)dbcmd()函数原型: #include #include RETCODE dbcmd(DBPROCESS* dbproc, const char cmdstrmg[])返回值:<1>执行成功时返回SUCCEED <2>执行失败时返回FAIL参数:<1>dbproc:已经连接到某个数据库的句柄,其实就是执行完dbuse()之后的句柄 <2>cmdstrmg:要执行的sql命令函数作用:这个函数最好在执行完dbuse之后运行,这个函数的作用其实就是将cmdstrmg这个SQL命令保存到dbproc指针指向的命令缓存中,等待运行(9)dbsqlexec()函数原型: #include #include RETCODE dbsqlexec(DBPROCESS* dbproc)返回值:<1>成功时返回SUCCEED <2>失败时返回FAIL参数:<1>保存了SQL命令的数据库连接句柄, 其实就是执行了dbcmd()函数之后的SQL连接句柄函数作用:将连接句柄中缓存中保存的命令送到数据库中执行, 并且等待执行的结果, 再将结果返回(10)dbresults()函数原型: #include #include RETCODE dbresults(DBPROCESS* dbproc)返回值:<1>函数执行成功时返回SUCCEED <2>函数执行失败时返回FAIL参数:dbproc:运行了dbsqlexec()函数之后的数据库连接句柄函数作用:这个函数的作用就是用来判断函数dbsqlexec()执行的命令是否执行成功(11)dbind()函数原型: #include #include RETCODE dbind(DBPROCESS* dbproc, int column, int vartype, DBINT valen, BYTE* varaddr)返回值:<1>函数执行成功时返回SUCCEED <2>函数执行失败时返回FAIL参数:<1>dbproc:保存了函数运行结果的数据库连接句柄 <2>column:你在数据库中查找到的数据的列数, 顺序以及sql语句为准, 起始数据为1 <3>vartype:数据的类型, 既是要接受从数据库取出来的本级数据的类型 <4>varlen:保存取出数据的本机数据的大小 <5>varaddr:保存取出数据的本机数据的地址指针函数作用:dbsqlexec()函数运行之后, 返回的结果不是单个数据, 而是多个数据的数据结果集合,
这个结果集合为行和列组成, 行就是一行数据,而列就是字段名称, 我们使用这个函数可以将结果集的column列的字段绑定到varaddr指向的本地的数据(12)dbnextrow()函数原型: #include #include RETCODE dbnextrow(DBPROCESS* dbproc)返回值:<1>NO_MORE_ROWS:结果集中没有更多的数据参数:<1>dbproc:保存了查询结果的数据库连接句柄函数作用:这个函数最好在dbind()函数调用之后调用, 我们在之前使用的dbind()函数, 将具体的字段和本机值绑定到了一起,
而dbnextrow()的作用就是查询结果集合中的下一行数据, 每当我们使用dbnextrow()函数的时候, 本地值中保存的绑定的指定的字段的值都会变为当前结果集那一行的对应字段的值(13)dbclose()函数原型: #include #include void dbclose(DBPROCESS* dbproc)返回值:无参数:dbproc:一个连接好数据库的连接句柄作用:关闭和数据库的连接, 并且释放这个连接句柄的资源相关代码:
[cpp] view
plain copy
-
-
#include
-
#include
-
-
-
DBINT result_code;
-
dbinit();
-
LOGINREC *loginrec = dblogin();
-
DBSETLUSER(loginrec, Q_SQLUser);
-
DBSETLPWD(loginrec, Q_SQLPassword);
-
DBPROCESS *dbprocess = dbopen(loginrec, Q_SQLServer);
-
-
if(dbprocess == FAIL)
-
{
-
fprintf(stderr, "Connect Fail
");
-
exit(EXIT_FAILURE);
-
}
-
else
-
{
-
printf("Connect success
");
-
}
-
-
if(dbuse(dbprocess, Q_SQLName) == FAIL)
-
{
-
dbclose(dbprocess);
-
exit(EXIT_FAILURE);
-
}
-
-
-
char mssqlbuf[1024];
-
memset(mssqlbuf, 0x00, sizeof(mssqlbuf));
-
sprintf(mssqlbuf, "SELECT name, age FROM testTable");
-
dbcmd(dbprocess, mssqlbuf);
-
-
if(dbsqlexec(dbprocess) == FAIL)
-
{
-
dbclose(dbprocess);
-
exit(EXIT_FAILURE);
-
}
-
-
char name[100];