zoukankan      html  css  js  c++  java
  • 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。如果它不能在你 的系统上编译–并且
    你没有使用MS DOS–这也许是一个bug.。
    FreeTDS的安装
    1.下载freetds-0.63版本(因为0.63版支持中文),点此下载
    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=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/
    关于安装参考: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 = 1433
    [myserver2]
    host = unixbox.mydomain.com
    port = 4000
    tds version = 5.0
    这个文件中global设置所有数据库使用tds版本为4.2,但在myserver2中使用的版本却是5.0,
    如果myserver2中没有这一项,那就是用4.2版本的如myserver。

    其配置项解释如下:
    tds version: 指明tds协议的版本,连接数据库时使用,如果在环境变量中没有设置
    此项,则由此配置决定,协议版本可取4.2,5.0,7.0,8.0。
    host: 数据库服务器的主机名或者ip地址。
    port: 数据库服务器的监听端口,可以取任何有效的端口值,一般而言Sybase SQL10以前为
    1433,10以上用5000,而Sybase SQLAnywhere 7是2638,Microsoft SQL server则用
    1433。此配置可以被环境变量中的TDSPORT改写。
    initial block size: 此值只能取512的倍数,默认为512,指定了协议块的最大值,
    一般不要改变此默认 配置。
    dump file: 任何有效的文件名,指明了转储文件的路径并且会打开日志记录。
    dump file append: yes或者no,决定是否追加保存到dump file文件中。
    timeout:设置处理的最大等待时间。
    connect timeout: 设置连接的最大等待时间。
    emulate little endian: yes或者no,是否强制大端机使用小端方式与MS Server通信。
    client charset: 任何有效的iconv字符集。默认值为ISO-8859-1,使FreeTDS使用
    iconv在数据库服务器和用户程序之间转换。
    FreeTDS函数
    RETCODE dbinit (  void   ) :
    功能:在你使用这个库之前调用此函数,为多个内部变量申请空间并且读取locales.conf(
    /usr/local/freetds/etc目录下)文件决定日期格式。
    返回值:SUCCEED (成功),FAIL(失败)
    LOGINREC* dblogin (  void   ) :
    功能:申请LOGINREC结构体。此结构体被传递到dbopen()函数用来创建与数据库的一个连接。
    返回值:NULL,没有申请到LOGINREC结构体,否则就是合法的地址。
    DBPROCESS * dbopen()
    功能:服务器建立一个连接. 传递 LOGINREC 指针和服务器名字
    返回值:成功则返回DBPROCESS结构体指针,保存与服务器连接的所有信息
    RETCODE dbcmd (  DBPROCESS *  dbproc, const char *  cmdstring ) 
    功能:填充SQL语句到命令缓冲区,cmdstring 所要填充的SQL语句字符串。
    返回值:返回SUCCEED 成功.,FAIL失败,没有足够的内存。
    RETCODE dbsqlexec (  DBPROCESS *  dbproc  ) 
    功能:发送SQL语句到服务器,并等待返回。
    返回值:SUCCEED:执行成功,FAIL,失败
    FreeTDS使用实例

     

    1. #include <stdio.h>
       2. #include <stdlib.h>
       3. #include <string.h>
       4. #include <unistd.h>
       5. 
       6. #include <sqlfront.h> /* sqlfront.h always comes first */
       7. #include <sybdb.h> /* sybdb.h is the only other file you need */
       8. 
       9. #define SQLDBIP " " //SQL数据库服务器IP

      10. #define SQLDBPORT " " //SQL数据库服务器端口

      11. #define SQLDBNAME " " //SQL数据库服务器数据库名

      12. #define SQLDBUSER " " //SQL数据库服务器数据库用户名

      13. #define SQLDBPASSWD " " //SQL数据库服务器用户密码

      14. #define SQLDBSERVER SQLDBIP":"SQLDBPORT
      15. 
      16. #define DBSQLCMD "select * from yancao"
      17. 
      18. int main(int argc, char *argv[])
      19. {
      20. int i, ch;
      21. LOGINREC *login; //描述客户端的结构体,在连接时被传递到服务器.

      22. DBPROCESS *dbproc; //描述连接的结构体,被dbopen()函数返回

      23. RETCODE erc; //库函数中最普遍的返回类型.

      24. 
      25. /*******************************************************************/
      26. //在开始调用本库函数前常常要先调用dbinit()函数

      27. if (dbinit() == FAIL) {
      28. fprintf(stderr, "%s:%d: dbinit() failed ",
      29. argv[0], __LINE__);
      30. exit(1);
      31. }
      32. //dblogin()函数申请 LOGINREC 结构体,此结构体被传递给dbopen()函数,用来创建一个连接。

      33. //虽然基本上不会调用失败,但是检查它!.

      34. if ((login = dblogin()) == NULL) {
      35. fprintf(stderr, "%s:%d: unable to allocate login structure ",
      36. argv[0], __LINE__);
      37. exit(1);
      38. }
      39. //LOGINREC结构体不能被直接访问,要通过以下宏设置,下面设置两个必不可少的域

      40. DBSETLUSER(login, SQLDBUSER);
      41. DBSETLPWD(login, SQLDBPASSWD); 
      42. /***************************************************************/
      43. //dbopen()与服务器建立一个连接. 传递 LOGINREC 指针和服务器名字

      44. if ((dbproc = dbopen(login, SQLDBSERVER)) == NULL) {
      45. fprintf(stderr, "%s:%d: unable to connect to %s as %s ",
      46. argv[0], __LINE__,
      47. SQLDBSERVER, SQLDBUSER);
      48. exit(1);
      49. }
      50. // 可以调用dbuser()函数选择我们使用的数据库名,可以省略,省略后使用用户默认数据库.

      51. if (SQLDBNAME && (erc = dbuse(dbproc, SQLDBNAME)) == FAIL) {
      52. fprintf(stderr, "%s:%d: unable to use to database %s ",
      53. argv[0], __LINE__, SQLDBNAME);
      54. exit(1);
      55. }
      56. /*****************************************************************/
      57. dbcmd(dbproc, DBSQLCMD);//将SQL语句填充到命令缓冲区

      58. printf(" ");
      59. if ((erc = dbsqlexec(dbproc)) == FAIL) {
      60. fprintf(stderr, "%s:%d: dbsqlexec() failed ", argv[0], __LINE__);
      61. exit(1); //等待服务器执行SQL语句,等待时间取决于查询的复杂度。

      62. }
      63. /****************************************************************/
      64. //在调用dbsqlexec()、dbsqlok()、dbrpcsend()返回成功之后调用dbresults()函数

      65. printf("then fetch results: ");
      66. int count = 0;
      67. while ((erc = dbresults(dbproc)) != NO_MORE_RESULTS) {
      68. struct col { //保存列的所有信息

      69. char *name; //列名字

      70. char *buffer; //存放列数据指针

      71. int type, size, status;
      72. } *columns, *pcol;
      73. int ncols;
      74. int row_code; 
      75. if (erc == FAIL) {
      76. fprintf(stderr, "%s:%d: dbresults failed ",
      77. argv[0], __LINE__);
      78. exit(1);
      79. } 
      80. ncols = dbnumcols(dbproc);//返回执行结果的列数目 

      81. if ((columns = calloc(ncols, sizeof(struct col))) == NULL) {
      82. perror(NULL);
      83. exit(1);
      84. }
      85. /* read metadata and bind. */
      86. for (pcol = columns; pcol - columns < ncols; pcol++) {
      87. int c = pcol - columns + 1;
      88. pcol->name = dbcolname(dbproc, c); //返回指定列的列名

      89. pcol->type = dbcoltype(dbproc, c);
      90. pcol->size = dbcollen(dbproc, c); 
      91. printf("%*s(%d)", 20, pcol->name, pcol->size);
      92. if ((pcol->buffer = calloc(1, 20)) == NULL) {
      93. perror(NULL);
      94. exit(1);
      95. }
      96. erc = dbbind(dbproc, c, NTBSTRINGBIND, //??

      97. 20, (BYTE*)pcol->buffer);
      98. if (erc == FAIL) {
      99. fprintf(stderr, "%s:%d: dbbind(%d) failed ",
     100. argv[0], __LINE__, c);
     101. exit(1);
     102. }
     103. erc = dbnullbind(dbproc, c, &pcol->status); //(5)

     104. if (erc == FAIL) {
     105. fprintf(stderr, "%s:%d: dbnullbind(%d) failed ",
     106. argv[0], __LINE__, c);
     107. exit(1);
     108. }
     109. }
     110. printf(" ");
     111. /* 打印数据 */
     112. while ((row_code = dbnextrow(dbproc)) != NO_MORE_ROWS) {//读取行数据

     113. switch (row_code) {
     114. case REG_ROW:
     115. for (pcol=columns; pcol - columns < ncols; pcol++) {
     116. char *buffer = pcol->status == -1?
     117. "null" : pcol->buffer;
     118. printf("%*s ", 20, buffer);
     119. }
     120. printf(" "); break;
     121. case BUF_FULL: break;
     122. case FAIL:
     123. fprintf(stderr, "%s:%d: dbresults failed ",
     124. argv[0], __LINE__);
     125. exit(1); break;
     126. default: // (7)

     127. printf("data for computeid %d ignored ", row_code);
     128. }
     129. }
     130. /* free metadata and data buffers */
     131. for (pcol=columns; pcol - columns < ncols; pcol++) {
     132. free(pcol->buffer);
     133. }
     134. free(columns);
     135. if (DBCOUNT(dbproc) > -1) /* 得到SQL语句影响的行数 */
     136. fprintf(stderr, "%d rows affected ", DBCOUNT(dbproc))
     137. }
     138. dbclose(dbproc);
     139. dbexit();
     140. }

  • 相关阅读:
    2014编程之美资格赛 第二题 大神和三个小伙伴
    操作系统PV操作——进程同步问题(C#实现)
    [转_管理]成功者必备的15种能力
    [技术相关]List、Dictionary转Dictionary的性能分析
    [项目管理]怎样评定软件开发成果的质量
    Visual Studio 2013 RTM 中文语言包官方下载地址发布
    IIS7报错:如果要使用托管的处理程序,请安装 ASP.NET
    HTTP请求方式中get和post的区别
    asp.net之动态页面和静态页面的区别
    HTML语言语法大全
  • 原文地址:https://www.cnblogs.com/wgx214/p/3444349.html
Copyright © 2011-2022 走看看