ubuntu下通过FreeTDS访问SqlServer(c++示例)

1、安装unixODBC

unixODBC是用于非Windows平台下的开放式数据库连接工具,可从官网下载:http://www.unixodbc.org/ 。unixODBC提供了对ODBC的支持,但它只是一个ODBC管理器,要连接实际的数据库还得提供对应数据库的ODBC驱动。

下载之后根据以下步骤安装:

tar -xvf unixODBC-2.3.7.tar.gz
cd unixODBC-2.3.7
./configure --prefix=/usr/local/unixODBC  #--prefix选项用于指定安装目录,不指定的话默认安装在/usr/local
make
sudo make install

使用以下命令测试unixODBC是否安装成功

odbcinst -j

如果成功显示以下信息说明安装完成

unixODBC 2.3.7
DRIVERS............: /etc/odbcinst.ini  
SYSTEM DATA SOURCES: /etc/odbc.ini  
FILE DATA SOURCES..: /etc/ODBCDataSources  
USER DATA SOURCES..: /home/robot/.odbc.ini  
SQLULEN Size.......: 8  
SQLLEN Size........: 8  
SQLSETPOSIROW Size.: 8

2、安装FreeTDS(主要是为了安装ODBC驱动)

FreeTDS是一组用于在unix和Linux下访问SqlServer和Sybase的程序库,提供ODBC驱动,可从官网下载: http://www.freetds.org/software.html 。(也可以直接安装微软提供的ODBC驱动程序:https://docs.microsoft.com/zh-cn/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017

下载之后根据以下步骤安装:

tar -xvf freetds-patched.tar.gz
cd freetds-1.00.111
./configure --prefix=/usr/local/freetds --with-tdsver=7.0 --enable-msdblib   #--with-tdsver选项用于指定TDS协议的版本,--enable-msdblib选项表示启用微软数据库函数库
make
sudo make install

安装完成后可以使用以下命令查看安装信息

tsql -C

如果出现以下信息说明安装完成

Version: freetds v1.00.111
freetds.conf directory: /usr/local/etc 
MS db-lib source conpatibility: yes
Sybase binary compatibility: no
Thread safety: yes
iconv library: yes
TDS version: 7.0
iODBC: no
unixobc: yes
SSPI "tursted" logins: no
Kerberos: no
OpenSSL: yes
GnuTLS: no
MARS: no

也可以使用tsql命令在终端中连接数据库

tsql -H 127.0.0.1 -p 1433 -U sa -P Robot123456

其中,-H 表示主机ip地址, -p 表示端口号,-U 表示用户名,-P 表示密码。如果出现以下信息表示连接成功

locale is "zh_CN.UTF-8"
locale charset is "UTF-8"
using default charset "UTF-8"
1>

3、c++连接数据库

至此,我们的准备工作已经完成,可以通过freetds提供的接口连接SQLServer数据库了。使用freetds时需要包含的头文件为sybdb.h、sybfront.h,需要连接的动态链接库为sybdb。

接下来介绍一下常用的函数,在此之前不得不先介绍几个变量:

    <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
 

初始化函数dbinit()

函数原型为 RETCODE dbinit(void);

返回值 RETCODE:<1>成功时返回SUCCEED  <2>失败时返回FAIL

登录信息结构体生成函数dblogin()

函数原型为 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          连接数据库的超时时间

登录信息相关选项的值设置函数dbsetlname()

函数原型 RETCODE dbsetlname(LOGINREC* login, const char* value, int which);

返回值 <1>成功时返回SUCCEED <2>失败时返回FAIL

参数 <1> LOGINREC*:一个LOGINREC指针
         <2> value:我们要设置的选项的值
         <3> which:我们要设置的选项                  

登录用户名设置函数DBSETLUSER()

函数原型 DBSETLUSER(LOGINREC* login, char* UserName);

返回值 RETCODE:<1>函数执行成功时返回SUCCEED <2>函数执行失败时返回FAIL

参数 <1>LOGINREC*:一个LOGINREC指针
        <2>UserName:登录数据库的用户名

登录密码设置函数DBSETLPWD()

函数原型 DBSETLPWD(LOGINREC* login, char* PassWord);

返回值 RETCODE:<1>函数执行成功时返回SUCCEED <2>函数执行失败时返回FAIL
参数 <1>LOGINREC*:一个LOGINREC指针
        <2>PassWord:登录数据库的用户的密码

数据库管理系统连接函数dbopen()

函数原型 DBPROCESS* dbopen(LOGINREC* login, const char* server);

返回值 <1>成功时返回DBPROCESS*, 一个成功连接到数据库的句柄
            <2>失败时返回NULL
参数 <1>LOGINREC*:一个LOGINREC指针, 指针中一定要保存了连接使用户的用户名称, 以及用户的密码
        <2>server:要连接数据库的IP地址

包含一系列数据表的具体数据库连接函数dbuse()

函数原型 RETCODE dbuse(DBPROCESS* dbproc, const char* name);

返回值 <1>成功时返回SUCCEED <2>失败时返回FAIL
参数 <1>dbproc:已经连接到数据库的连接句柄
        <2>name:要使用的数据库的名字

SQL命令提交函数dbcmd()

函数原型 RETCODE dbcmd(DBPROCESS* dbproc, const char cmdstrmg[]);
返回值 <1>执行成功时返回SUCCEED <2>执行失败时返回FAIL
参数 <1>dbproc:已经连接到某个数据库的句柄
        <2>cmdstrmg:要执行的sql命令

注意:dbcmd()函数其实是将SQL命令保存到dbproc指针指向的命令缓存中,不会立即执行

SQL命令执行函数dbsqlexec()

函数原型 RETCODE dbsqlexec(DBPROCESS* dbproc);

返回值 <1>成功时返回SUCCEED <2>失败时返回FAIL
参数  dbproc:保存了SQL命令的数据库连接句柄

SQL命令执行成功与否的判断函数dbresults()

函数原型 RETCODE dbresults(DBPROCESS* dbproc);

返回值 <1>函数执行成功时返回SUCCEED <2>函数执行失败时返回FAIL
参数  dbproc:运行了dbsqlexec()函数之后的数据库连接句柄

SQL命令查询结果返回函数dbind()

函数原型 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:保存取出数据的本地内存的地址指针

结果集合中下一行数据查询函数dbnextrow()

函数原型 RETCODE dbnextrow(DBPROCESS* dbproc);

返回值 <1>NO_MORE_ROWS:结果集中没有更多的数据
参数 <1>dbproc:保存了查询结果的数据库连接句柄

关闭数据库连接函数dbclose()

函数原型 void dbclose(DBPROCESS* dbproc);

参数 dbproc:一个连接好数据库的连接句柄

数据库连接测试

新建一个文本文件,重命名为test.cpp,并写入以下内容:

    #include <stdio.h>  
    #include <string.h>  
    #include <stdlib.h>  
    #include <unistd.h>   
       
    #include <sybfront.h> //freetds头文件  
    #include <sybdb.h> //freetds头文件  
       
       
    int main(void)  
    {  
        char szUsername[32] = "sa";  
        char szPassword[32] = "Robot123456";  
        char szDBName[32] = "TestDB"; //数据库名  
        char szServer[32] = "127.0.0.1:1433";//数据库服务器:端口  
       
        //初始化db-library  
        dbinit();  
             
        //连接数据库  
        LOGINREC *loginrec = dblogin();  
        DBSETLUSER(loginrec, szUsername);         
        DBSETLPWD(loginrec, szPassword);  
        DBPROCESS *dbprocess = dbopen(loginrec, szServer);//连接数据库  
        if(dbprocess == FAIL)  
        {  
            printf("Conect to MS SQL SERVER fail, exit!\n");  
            return -1;   
        }  
        printf("Connect to MS SQL SERVER success!\n");  
             
        if(dbuse(dbprocess, szDBName) == FAIL)  
            printf("Open database failed!\n");  
        else  
            printf("Open database success!\n");  
             
       
        //关闭数据库连接  
        dbclose(dbprocess);  
      
        return 0;  
    }    

打开一个终端,进入该文件所在目录并输入以下命令进行编译:

g++ test.cpp -o test

结果报错:

未定义的引用,说明编译时没有连接包含该函数定义的动态链接库(如果是“未声明的引用”,则是因为包含该函数声明的头文件未成功添加)。这里添加上sybdb动态链接库再重新编译:

g++ test.cpp -o test -l sybdb

 结果显示上述报错消失,但又产生了新的报错信息:

意思是共享链接库sybdb中调用了其他共享链接库中的函数,而包含这些函数的共享链接库未连接。通过查询搜索引擎得知,openssl提供了两个库:ssl crypto,如果要二次开发需要连接这两个共享库。于是添加上这两个库再重新编译:

g++ test.cpp -o test -l sybdb -l ssl -l crypto

可成功完成编译,并生产可执行文件test。在终端中运行 ./test 即可运行,运行结果如下说明数据库连接成功:

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值