freetds简介、安装、配置及使⽤介绍
什么是FreeTDS
  简单的说FreeTDS是⼀个程序库,可以实现在Linux系统下访问微软的SQL数据库! FreeTDS 是⼀个开源(如果你喜欢可以称为⾃由)的程序库,是TDS(表列数据流)协议的再次实现。它可以被⽤在Sybase的db-lib或者ct-lib库。它也包含⼀个ODBC的库。允许许多开源的应⽤软件⽐如Perl和PHP(或者你⾃⼰的c或C++程序)去连接到Sybase或 Microsoft SQL服务器。FreeTDS 以源码的形式被发布,⼏乎可以在任何操作系统上编译。意味着Unix和类Unix系统(包括著名的分⽀如Interix 和QNX),还有Win32,VMS,和OSX。
2.将其解压到任意⽬录,进⼊到解压后的⽂件夹⾥。
3.切换到root,配置: ./configure –prefix=/usr/local/freetds –with-tdsver=8.0 –enable-msdblib 解释:–prefix为设置FreeTDS 的安装⽬录,–with-tdsver是设置TDS版本, –enable-msdblib为是否允许Microsoft数据库函数库
4.make & make install
5.配置环境变量:vim ~/.bashrc向此⽂件中加⼊: export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/
usr/local/freetds/lib/ FreeTDS测试:
FreeTDS安装好了,接下来就可以查看下FreeTDS状态了;
运⾏./tsql  -C ,在安装⽬录的bin⽬录下可以到tsql ,查看终端打印出来信息,这个-with-tdsver=7.1:
FreeTDS的配置
  freeTDS 的配置⽂件,FreeTDS也⽀持⼀个旧的配置⽂件interfaces,但请使⽤f 除⾮你的环境必须使⽤interfaces。FreeTDS⾸先f⽂件如果没有到才去 interfaces⽂件。 f⽂件默认
在/usr/local/freetds/etc⽬录下,但是可以在configure时配置 sysconfdir选项,这个选项就是f⽂件所存在的⽬录。f配置⽂件分为两部分:⼀是[global]部分,另外⼀个是[dataserver]部分,其中 [dataserver]对应⼀个数据库。在golbal 中的设置是对全部数据库起作⽤的,但在dataserver 部分的设置只对⾃⼰的数据库起作⽤,并且可以覆盖全局的设置。
例如: f⽂件:
[global]
tds version = 4.2
[myserver]
host = domain
port = 1433
[myserver2]
host = domain
port = 4000
tds version = 5.0
  这个⽂件中global设置所有数据库使⽤tds版本为4.2,但在myserver2中使⽤的版本却是5.0,如果myserver2中没有这⼀项,那就是⽤4.2版本的如myserver。
其配置项解释如下:
ltds version      : 指明tds协议的版本,连接数据库时使⽤,如果在环境变量中没有设置此项,则由此配置决定,协议版本可取4.2,5.0,7.0,8.0。
html三张图片并列居中
lhost                : 数据库服务器的主机名或者ip地址。
lport                : 数据库服务器的监听端⼝,可以取任何有效的端⼝值,⼀般⽽⾔Sybase SQL10以前为 1433,10以上⽤5000,⽽Sybase SQLAnywhere 7是2638,Microsoft SQL server则⽤ 1433。此配置可以被环境变量中的TDSPORT改写。linitial block size : 此值只能取512的倍数,默认为512,指定了协议块的最⼤值,⼀般不要改变此默认配置。
ldump file          : 任何有效的⽂件名,指明了转储⽂件的路径并且会打开⽇志记录。
ldump file append: yes或者no,决定是否追加保存到dump file⽂件中。
ltimeout            :设置处理的最⼤等待时间。
lconnect timeout:设置连接的最⼤等待时间。
lclient charset  : 任何有效的iconv字符集。默认值为ISO-8859-1,使FreeTDS使⽤ iconv在数据库服务器和⽤户程序之间转换。FreeTDS函数
1. Dbcmd和dbfcmd
函数原形: Dbcmd(DBPROCESS *proc,char * sql);
    Dbcmd(DBPROCESS *proc, char * format,char *args);
功能:该函数主要是构造sql语句,⼀个是带参数的,⼀个不带参数。
2. Dbsqlexec
函数原形:Dbsqlexec(DBPROCESS *proc);
功能:该函数负责执⾏你所构造的sql语句。
3. Dbresults
函数原形:Dbrerults(DBPROCESS *proc);
功能:得到sql语句的执⾏结果。返回值如果为NO_MORE_RESULTS=0,表明sql查询为空值(就是没有⼀条满⾜条件的结果),如果为(FAIL)=-1,表明查询出错,如果为(SUCCESS)=1,表明有结果且不为空。
java多线程调用同一个接口
4. DBROWS(全⼤写)
函数原形:DBROWS(DBPROCESS *proc);
功能:取出⼀⾏记录的信息。
5. Dbbind
函数原形:Dbbind(DBPROCESS *proc,int colmn,
功能:将sql查询出来的结果绑定到⼀个变量。第⼀个参数为从数据库那⾥拿的句柄,第⼆个参数是对应你的select语句中查询需要的字段(注:必须是按照select顺序绑定的,例如select user,password from hist1 ,如果值为1,就是绑定的user),第三个参数是绑定字段的类型,最后⼀个参数是绑定的变量。
6.    Dbnextrow
函数原形:Dbnextrow(DBPROCESS *proc);
功能:该函数将取出满⾜sql语句的每⼀⾏,返回值为0,代表处理结束,返回值为-1出错。
7.  Dbcancel
函数原形:Dbcancel(DBPROCESS *proc);
功能:清空上次查询得到的数据集,如果是⼀个句柄的话,每次重新执⾏select语句之前都要调⽤它清空结果,不然数据库会报错的。
8. Dbclose
函数原形:Dbclose(DBPROCESS *proc);
功能:关闭句柄。当不再使⽤时必须关闭句柄。
9.  Dbinit
函数原形:Dbinit()
功能:初识化数据库连接。返回值为-1出错。
10. Dblogin
函数原形:LOGINREC      *Dblogin();
DBSETLUSER(login,SOFT);  //set the database user
DBSETLPWD(login,SOFTPASS);//set password
功能:根据⽤户名和密码连接数据库。
11.Dbcount
函数原形:Dbcount(DBPROCESS *proc);
mysql语句的执行顺序功能:该函数将得到sql结果集被处理的⾏数,可以⽤它来判断你的select语句是否得到正确的处理。12.Dbopen
函数原形:DBPROCESS * Dbopen(LOGINREC    *login,NULL);
功能:返回⼀个操作数据库的句柄。win7批处理命令大全
另外再介绍两个关于数据库的出错信息的函数:
dberrhandle(int *err);
dbmsghandle(int* err);
实例代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sqlfront.h> /* sqlfront.h always comes first */
#include <sybdb.h> /* sybdb.h is the only other file you need */
#define SQLDBIP " " //SQL数据库服务器IP
#define SQLDBPORT " " //SQL数据库服务器端⼝
#define SQLDBNAME " " //SQL数据库服务器数据库名
#define SQLDBUSER " " //SQL数据库服务器数据库⽤户名
#define SQLDBPASSWD " " //SQL数据库服务器⽤户密码
#define SQLDBSERVER SQLDBIP":"SQLDBPORT
#define DBSQLCMD "select * from yancao"
int main(int argc, char *argv[])
{
int i, ch;
LOGINREC *login; //描述客户端的结构体,在连接时被传递到服务器.ascii码对什么进行编码
DBPROCESS *dbproc; //描述连接的结构体,被dbopen()函数返回
RETCODE erc; //库函数中最普遍的返回类型.
/*************************************************************/
//在开始调⽤本库函数前常常要先调⽤dbinit()函数
if (dbinit() == FAIL) {
fprintf(stderr, "%s:%d: dbinit() failed\n",argv[0], __LINE__);
exit(1);
}
//dblogin()函数申请 LOGINREC 结构体,此结构体被传递给dbopen()函数,⽤来创建⼀个连接。
//虽然基本上不会调⽤失败,但是检查它!.
if ((login = dblogin()) == NULL) {
fprintf(stderr, "%s:%d: unable to allocate login structure\n",argv[0],__LINE__);
exit(1);
}
//LOGINREC结构体不能被直接访问,要通过以下宏设置,下⾯设置两个必不可少的域
DBSETLUSER(login, SQLDBUSER);
DBSETLPWD(login, SQLDBPASSWD);
/*************************************************************/
//dbopen()与服务器建⽴⼀个连接. 传递 LOGINREC 指针和服务器名字
if ((dbproc = dbopen(login, SQLDBSERVER)) == NULL) {
fprintf(stderr, "%s:%d: unable to connect to %s as %s\n",
argv[0], __LINE__,
SQLDBSERVER, SQLDBUSER);
}
// 可以调⽤dbuser()函数选择我们使⽤的数据库名,可以省略,省略后使⽤⽤户默认数据库.    if (SQLDBNAME && (erc = dbuse(dbproc, SQLDBNAME)) == FAIL) {
fprintf(stderr, "%s:%d: unable to use to database %s\n",
argv[0], __LINE__, SQLDBNAME);
exit(1);
}
/*************************************************************/
dbcmd(dbproc, DBSQLCMD);//将SQL语句填充到命令缓冲区
printf("\n");
if ((erc = dbsqlexec(dbproc)) == FAIL) {
fprintf(stderr, "%s:%d: dbsqlexec() failed\n", argv[0], __LINE__);
exit(1); //等待服务器执⾏SQL语句,等待时间取决于查询的复杂度。
}
/*************************************************************/
/
/在调⽤dbsqlexec()、dbsqlok()、dbrpcsend()返回成功之后调⽤dbresults()函数
printf("then fetch results:\n");
int count = 0;
while ((erc = dbresults(dbproc)) != NO_MORE_RESULTS) {
struct col { //保存列的所有信息
char *name; //列名字
char *buffer; //存放列数据指针
int type, size, status;
} *columns, *pcol;
int ncols;
int row_code;
if (erc == FAIL) {
fprintf(stderr, "%s:%d: dbresults failed\n",
argv[0], __LINE__);
exit(1);
}
ncols = dbnumcols(dbproc);//返回执⾏结果的列数⽬
if ((columns = calloc(ncols, sizeof(struct col))) == NULL) {
perror(NULL);
exit(1);
}
/* read metadata and bind. */
for (pcol = columns; pcol - columns < ncols; pcol++) {
int c = pcol - columns + 1;
pcol->name = dbcolname(dbproc, c); //返回指定列的列名
winform的richtextbox添加字符串pcol->type = dbcoltype(dbproc, c);
pcol->size = dbcollen(dbproc, c);
printf("%*s(%d)", 20, pcol->name, pcol->size);
if ((pcol->buffer = calloc(1, 20)) == NULL) {
perror(NULL);
exit(1);
}
erc = dbbind(dbproc, c, NTBSTRINGBIND, 20, (BYTE*)pcol->buffer);
if (erc == FAIL) {
fprintf(stderr, "%s:%d: dbbind(%d) failed\n",
argv[0], __LINE__, c);
exit(1);
}
erc = dbnullbind(dbproc, c, &pcol->status); //(5)
if (erc == FAIL) {
fprintf(stderr, "%s:%d: dbnullbind(%d) failed\n",
argv[0], __LINE__, c);
exit(1);
}
}
printf("\n");
while ((row_code = dbnextrow(dbproc)) != NO_MORE_ROWS) {//读取⾏数据    switch (row_code) {
case REG_ROW:
for (pcol=columns; pcol - columns < ncols; pcol++) {
char *buffer = pcol->status == -1?
"null" : pcol->buffer;
printf("%*s ", 20, buffer);
}
printf("\n"); break;
case BUF_FULL: break;
case FAIL:
fprintf(stderr, "%s:%d: dbresults failed\n",
argv[0], __LINE__);
exit(1); break;
default: // (7)
printf("data for computeid %d ignored\n", row_code);
}
}
/* free metadata and data buffers */
for (pcol=columns; pcol - columns < ncols; pcol++) {
free(pcol->buffer);
}
free(columns);
if (DBCOUNT(dbproc) > -1) /* 得到SQL语句影响的⾏数 */
fprintf(stderr, "%d rows affected\n", DBCOUNT(dbproc))
}
dbclose(dbproc);
dbexit();
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。