什么是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,点此下载 https://www.jb51.net/database/201983.html
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:
关于安装参考
http://linux.chinaunix.net/techdoc/database/2008/10/31/1042291.shtml 或者:http://www.linuxdiyf.com/viewarticle.php" " //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[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);
exit(1);
}
// 可以调用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); //返回指定列的列名
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();
}
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]