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。
FreeTDS的安装
1.下载freetds,点此下载 http://www.ibiblio.org/pub/Linux/ALPHA/freetds/old/0.63/freetds-0.63.tar.gz
2.将其解压到任意目录,进入到解压后的文件夹里。
3.切换到root,配置: ./configure –prefix=/usr/local/freetds –with-tdsver=7.1 –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:
关于安装参考
http://linux.chinaunix.net/techdoc/database/2008/10/31/1042291.shtml 或者:http://www.linuxdiyf.com/viewarticle.php?id=109086
FreeTDS的配置
freeTDS 的配置文件,FreeTDS也支持一个旧的配置文件interfaces,但请使用freetds.conf 除非你的环境必须使用interfaces。FreeTDS首先找freetds.conf文件如果没有找到才去找 interfaces文件。 freetds.conf文件默认在/usr/local/freetds/etc目录下,但是可以在configure时配置 sysconfdir选项,这个选项就是freetds.conf文件所存在的目录。freetds.conf配置文件分为两部分:一是[global]部分,另外一个是[dataserver]部分,其中 [dataserver]对应一个数据库。在golbal中的设置是对全部数据库起作用的,但在dataserver 部分的设置只对自己的数据库起作用,并且可以覆盖全局的设置。
例如: freetds.conf文件:
[global]
tds version = 4.2
[myserver]
host = ntbox.mydomain.com
port =
[myserver2]
host = unixbox.mydomain.com
port =
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。
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: 设置连接的最大等待时间。
lemulate little endian: yes或者no,是否强制大端机使用小端方式与MS Server通信。
lclient charset : 任何有效的iconv字符集。默认值为ISO-8859-1,使FreeTDS使用 iconv在数据库服务器和用户程序之间转换。
FreeTDS函数
详细解释:http://technet.microsoft.com/en-us/library/aa937082(v=sql.80).aspx
1. dbcmd和dbfcmd
函数原形: Dbcmd(DBPROCESS *proc,char * sql);
Dbcmd(DBPROCESS *proc, char * format,char *args);
功 能:该函数主要是构造sql语句,一个是带参数的,一个不带参数。
2. dbsqlexec
函数原形:Dbsqlexec(DBPROCESS *proc);
功 能:This function sends Transact-SQL statements, stored in the command buffer of the DBPROCESS, to SQL Server。
3. dbresults
函数原形:Dbrerults(DBPROCESS *proc);
功 能:得到sql语句的执行结果。返回值如果为NO_MORE_RESULTS=0,表明sql查询为空值(就是没有一条满足条件的结果),如果为(FAIL)=-1,表明查询出错,如果为(SUCCESS)=1,表明有结果且不为空。
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);
功 能:该函数将得到sql结果集被处理的行数,可以用它来判断你的select语句是否得到正确的处理。
12.dbopen
函数原形:DBPROCESS * Dbopen(LOGINREC *login,NULL);
功 能:返回一个操作数据库的句柄。
另外再介绍两个关于数据库的出错信息的函数:
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; //描述客户端的结构体,在连接时被传递到服务器.
DBPROCESS *dbproc; //描述连接的结构体,被dbopen()函数返回
RETCODE erc; //库函数中最普遍的返回类型.
/*************************************************************/
//在开始调用本库函数前常常要先调用dbinit()函数
if (dbinit() == FAIL) {
fprintf(stderr, "%s:%d: dbinit() failed\n",argv[], __LINE__);
exit();
}
//dblogin()函数申请 LOGINREC 结构体,此结构体被传递给dbopen()函数,用来创建一个连接。
//虽然基本上不会调用失败,但是检查它!.
if ((login = dblogin()) == NULL) {
fprintf(stderr, "%s:%d: unable to allocate login structure\n",argv[],__LINE__);
exit();
}
//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[], __LINE__,
SQLDBSERVER, SQLDBUSER);
exit();
}
// 可以调用dbuser()函数选择我们使用的数据库名,可以省略,省略后使用用户默认数据库.
if (SQLDBNAME && (erc = dbuse(dbproc, SQLDBNAME)) == FAIL) {
fprintf(stderr, "%s:%d: unable to use to database %s\n",
argv[], __LINE__, SQLDBNAME);
exit();
}
/*************************************************************/
dbcmd(dbproc, DBSQLCMD);//将SQL语句填充到命令缓冲区
printf("\n");
if ((erc = dbsqlexec(dbproc)) == FAIL) {
fprintf(stderr, "%s:%d: dbsqlexec() failed\n", argv[], __LINE__);
exit(); //等待服务器执行SQL语句,等待时间取决于查询的复杂度。
}
/*************************************************************/
//在调用dbsqlexec()、dbsqlok()、dbrpcsend()返回成功之后调用dbresults()函数
printf("then fetch results:\n");
int count = ;
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[], __LINE__);
exit();
}
ncols = dbnumcols(dbproc);//返回执行结果的列数目
if ((columns = calloc(ncols, sizeof(struct col))) == NULL) {
perror(NULL);
exit();
}
/* read metadata and bind. */
for (pcol = columns; pcol - columns < ncols; pcol++) {
int c = pcol - columns + ;
pcol->name = dbcolname(dbproc, c); //返回指定列的列名
pcol->type = dbcoltype(dbproc, c);
pcol->size = dbcollen(dbproc, c);
printf("%*s(%d)", , pcol->name, pcol->size);
if ((pcol->buffer = calloc(, )) == NULL) {
perror(NULL);
exit();
}
erc = dbbind(dbproc, c, NTBSTRINGBIND, , (BYTE*)pcol->buffer);
if (erc == FAIL) {
fprintf(stderr, "%s:%d: dbbind(%d) failed\n",
argv[], __LINE__, c);
exit();
}
erc = dbnullbind(dbproc, c, &pcol->status); //(5)
if (erc == FAIL) {
fprintf(stderr, "%s:%d: dbnullbind(%d) failed\n",
argv[], __LINE__, c);
exit();
}
}
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 == -?
"null" : pcol->buffer;
printf("%*s ", , buffer);
}
printf("\n"); break;
case BUF_FULL: break;
case FAIL:
fprintf(stderr, "%s:%d: dbresults failed\n",
argv[], __LINE__);
exit(); 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) > -) /* 得到SQL语句影响的行数 */
fprintf(stderr, "%d rows affected\n", DBCOUNT(dbproc))
}
dbclose(dbproc);
dbexit();
}
参考:
2.TDS协议解析
3.TDS函数查阅
freetds相关的更多相关文章
- Linux下用freetds执行SQL Server的sql语句和存储过程
Linux下用freetds执行SQL Server的sql语句和存储过程 http://www.linuxidc.com/Linux/2012-06/61617.htm freetds相关 http ...
- windows程序移植linux
1,路径名统一用正斜杠“/”.(windows下正反斜杠都识别,linux只认正斜杠.) 2,统一使用UTF-8格式编码. vim中无法保存汉字时,可输入下列命令: :set fileencoding ...
- 嵌入式单片机STM32应用技术(课本)
目录SAIU R20 1 6 第1页第1 章. 初识STM32..................................................................... ...
- java中的字符串相关知识整理
字符串为什么这么重要 写了多年java的开发应该对String不陌生,但是我却越发觉得它陌生.每学一门编程语言就会与字符串这个关键词打不少交道.看来它真的很重要. 字符串就是一系列的字符组合的串,如果 ...
- SQL Server相关书籍
SQL Server相关书籍 (排名不分先后) Microsoft SQL Server 企业级平台管理实践 SQL Server 2008数据库技术内幕 SQL Server性能调优实战 SQL S ...
- dotNET跨平台相关文档整理
一直在从事C#开发的相关技术工作,从C# 1.0一路用到现在的C# 6.0, 通常情况下被局限于Windows平台,Mono项目把我们C#程序带到了Windows之外的平台,在工作之余花了很多时间在M ...
- 在ASP.NET Core应用中如何设置和获取与执行环境相关的信息?
HostingEnvironment是承载应用当前执行环境的描述,它是对所有实现了IHostingEnvironment接口的所有类型以及对应对象的统称.如下面的代码片段所示,一个HostingEnv ...
- virtualbox linux虚拟机相关
linux虚拟机设置为静态IP 在virtualbox中安装好linux虚拟机后,如果采用的是NAT方式的话,linux虚拟机默认采用dhcp方式自动上网,而且用的是NetworkManager服务而 ...
- WebGIS中等值面展示的相关方案简析
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 等值面是气象.环保等相关项目上常用到的效果展示.在传统的CS项 ...
随机推荐
- Oracle中用一个表的数据更新另一个表的数据
update tbl1 a set (a.col1, a.col2) = (select b.col1, b.col2 from tbl2 ...
- leetcode:Remove Linked List Elements
Remove all elements from a linked list of integers that have value val. ExampleGiven: 1 --> 2 --& ...
- MFC弹出菜单隐藏解决
http://social.msdn.microsoft.com/Forums/en-US/5482103e-272b-4c9f-bac4-be15f14782bd/cmfcmenubar-remov ...
- 【转载】正则表达式学习 & ASCII码表
文章原地址: http://www.jb51.net/tools/zhengze.html <正则表达式30分钟入门教程> 其中有几个地方可以有笔记: \s 匹配任意的空白符 \b 匹配单 ...
- openfire源码分析
启动流程 Socket接口 Socket通信使用Mina框架实现,是XMPP协议的处理入口,具体为: 消息接收后由不同的节处理器处理: StanzaHandler基础消息类型,之后进行消息路由: 最后 ...
- POJ 1436 (线段树 区间染色) Horizontally Visible Segments
这道题做了快两天了.首先就是按照这些竖直线段的横坐标进行从左到右排序. 将线段的端点投影到y轴上,线段树所维护的信息就是y轴区间内被哪条线段所覆盖. 对于一条线段来说,先查询和它能相连的所有线段,并加 ...
- Codeforces 435 A Queue on Bus Stop
题意:给出n队人坐车,车每次只能装载m人,并且同一队的人必须坐同一辆车,问最少需要多少辆车 自己写的时候想的是从前往后扫,看多少队的人的和小于m为同一辆车,再接着扫 不过写出来不对 后来发现把每一队的 ...
- [转]就这样,创建了自己的运行时共享库(RSL)
原文地址:http://riaoo.com/?p=1405 博客园的下载地址(版权归原作者) http://files.cnblogs.com/tianlanliao/CustomRSL.zip 创建 ...
- PL/SQL 下邮件发送程序
对DBA而言,尽管在os级别下发送邮件是轻而易举的事情,然而很多时候我们也需要在PL/SQL中来发送邮件,比如监控job的执行状况等.本文根据网友(源作者未考证)的代码将其改装并封装到了package ...
- linux xampp eclipse xdebug 无法进入断点
一.xampp 版本 1.8.3-5 xampp安装后会自动集成xdebug,目录一般为 /opt/lampp/lib/php/extensions/***-debug-***目录 关于php 与ph ...