FreeTDS从Linux访问Windows SqlServer数据库

提示 \color{red}{提示} 提示:
《Linux系统上安装FreeTDS》中讲述了如何安装包管理工具自带的的FreeTDS软件包。
《Linux系统上编译安装FreeTDS库文件》中讲述了如何编译FreeTDS源码,并安装。
《FreeTDS库文件在C++代码中的简单应用》中介绍了一个简单的C++用例。

本文内容在前面三篇文章的基础上进行深入。

本文内容所使用的环境

  • Windows系统:Windows 10 企业版 64位操作系统;IP:192.168.1.130
  • Linux系统:BigCloud Enterprise Linux 8.2 (Core);IP:192.168.1.110
  • 数据库:Microsoft SQL Server 2008 (RTM) Enterprise Edition,安装在Windows系统上,默认端口:1433

需求背景

XXX C++程序运行在Linux系统上,使用技术手段,使得C++程序不仅可以访问Linux系统上的SQLServer数据库,也能访问Windows系统上的SQLServer数据库,以应对复杂的应用场景需求。

1.首先验证网络问题

  • Linux系统和Windows系统网络连接是否可达,可以使用ping命令行工具

  • 数据库端口1433是否开放,可以使用telnet命令行工具

    [root@localhost ~]# ping 192.168.1.130
    PING 192.168.1.130 (192.168.1.130) 56(84) bytes of data.
    64 bytes from 192.168.1.130: icmp_seq=1 ttl=128 time=1.01 ms
    64 bytes from 192.168.1.130: icmp_seq=2 ttl=128 time=0.503 ms
    64 bytes from 192.168.1.130: icmp_seq=3 ttl=128 time=0.522 ms
    64 bytes from 192.168.1.130: icmp_seq=4 ttl=128 time=0.624 ms
    64 bytes from 192.168.1.130: icmp_seq=5 ttl=128 time=0.500 ms
    64 bytes from 192.168.1.130: icmp_seq=6 ttl=128 time=0.531 ms
    64 bytes from 192.168.1.130: icmp_seq=7 ttl=128 time=0.509 ms
    ^C
    --- 192.168.1.130 ping statistics ---
    7 packets transmitted, 7 received, 0% packet loss, time 110ms
    rtt min/avg/max/mdev = 0.500/0.600/1.012/0.173 ms
    [root@localhost ~]# ^C
    [root@localhost ~]# telnet 192.168.1.130 1433
    Trying 192.168.1.130...
    Connected to 192.168.1.130.
    Escape character is '^]'.
    ^]
    telnet> quit
    Connection closed.
    [root@localhost ~]#

测试后网络连接和端口都是通的。如果测试后不通,需要先解决网络连接问题。

2.使用tsql工具尝试连接数据库

在Windows系统的SqlServer2008数据库管理系统上新建一个数据为:fy2000 ,登陆用户名:sa,密码:123456

[root@localhost ~]# tsql -H 192.168.1.130 -p 1433 -U sa -P 123456 -D fy2000
locale is "zh_CN.UTF-8"
locale charset is "UTF-8"
using default charset "UTF-8"
Setting fy2000 as default database in login packet
Error 20002 (severity 9):
	Adaptive Server connection failed
Error 20002 (severity 9):
	Adaptive Server connection failed
There was a problem connecting to the server
[root@localhost ~]# 

可以看到无法直接访问。查阅官网 《用户指南》 第一章中 《History of TDS Versions》章节,怀疑是使用的版本不对导致的。

3.查看Linux系统上FreeTDS的版本

[root@localhost ~]# tsql -C
Compile-time settings (established with the "configure" script)
                            Version: freetds v1.5.dev.20240410
             freetds.conf directory: /usr/local/etc
     MS db-lib source compatibility: yes
        Sybase binary compatibility: no
                      Thread safety: yes
                      iconv library: yes
                        TDS version: 7.4
                              iODBC: no
                           unixodbc: yes
              SSPI "trusted" logins: no
                           Kerberos: no
                            OpenSSL: yes
                             GnuTLS: no
                               MARS: yes
[root@localhost ~]# 

可以看到,Linux上的FreeTDS的版本是7.4,这个版本是专门为 SQL Server 2012 及以上版本服务的,不兼容 SQL Server 2008.

因此,我们需要换用一个支持 SQL Server 2008 的版本,比如官网上说的 7.3。

4. 切换FreeTDS版本

《Linux系统上编译安装FreeTDS库文件》中,编译的时候有指定版本7.4,即命令:

./configure --prefix=/usr/local --with-tdsver=7.4 --enable-msdblib

  • 第一种方式:重新编译一个7.3的版本进行尝试。--->这种没有进行尝试。

  • 第二种方式:修改 freetds.conf 配置文件,设置别名,在别名里面设置使用连接的版本号。如下:

    This file is installed by FreeTDS if no file by the same

    name is found in the installation directory.

    For information about the layout of this file and its settings,

    see the freetds.conf manpage "man freetds.conf".

    Global settings are overridden by those in a database

    server specific section

    [global]
    # TDS protocol version
    tds version = auto

    =======[此处省略了global下的部分内容]=======<<<<<<<<<<<<<<<<<<<<<<

    A typical Sybase server

    [egServer50]
    host = symachine.domain.com
    port = 5000
    tds version = 5.0

    A typical Microsoft server

    [egServer73]
    host = ntmachine.domain.com
    port = 1433
    tds version = 7.3

    The server you added yourself

    [myWin130]
    host = 192.168.1.130
    port = 1433
    tds version = 7.3

然后再尝试进行连接,使用别名的参数选项为 -S

[root@localhost ~]# tsql -S myWin130 -U sa -P 123456 -D fy2000
locale is "zh_CN.UTF-8"
locale charset is "UTF-8"
using default charset "UTF-8"
Setting fy2000 as default database in login packet
Error 20002 (severity 9):
	Adaptive Server connection failed
There was a problem connecting to the server
[root@localhost ~]#

到这里发现还是不行,此时可以尝试一下其它版本号是否可行。

5. 尝试切换其它的FreeTDS版本号

官网给出的版本号有如下几种

  • TDS 4.2 Sybase and Microsoft:这个版本是在Microsoft和Sybase分家之前的通用版本,兼容两者。
  • TDS 5.0 Sybase:专门为Sybase类型数据库引入的
  • TDS 7.0 Microsoft:为SQL Server 7.0引入。包括对SQL Server 7.0中扩展数据类型的支持,它还支持Unicode。
  • TDS 7.1 Microsoft:专门为SQL Server 2000引入的。
  • TDS 7.2 Microsoft:专门为SQL Server 2005引入的。
  • TDS 7.3 Microsoft:专门为SQL Server 2008引入的。
  • TDS 7.4 Microsoft:为SQL Server 2012及以上版本引入的。

由于7.4,7.3尝试失败。5.0、7.1、7.2都不是为SQL Server 2008引入的,都可以忽略(有兴趣的可以尝试以下),只剩下4.2和7.0两个版本可以尝试。

  • 尝试4.2版本:
    修改配置

    The server you added yourself

    [myWin130]
    host = 192.168.1.130
    port = 1433
    tds version = 4.2

尝试连接

[root@localhost ~]# tsql -S myWin130 -U sa -P 123456 -D fy2000
locale is "zh_CN.UTF-8"
locale charset is "UTF-8"
using default charset "UTF-8"
Setting fy2000 as default database in login packet
1> select * from tb_student_info
2> go
name	class	age	hight
小美	2	18	123
小红	6	35	130
小兵	3	25	234
(3 rows affected)
1> quit
[root@localhost ~]# 
  • 尝试7.0版本
    修改配置

    The server you added yourself

    [myWin130]
    host = 192.168.1.130
    port = 1433
    tds version = 7.0

尝试连接

[root@localhost ~]# tsql -S myWin130 -U sa -P 123456 -D fy2000
locale is "zh_CN.UTF-8"
locale charset is "UTF-8"
using default charset "UTF-8"
Setting fy2000 as default database in login packet
1> select * from tb_student_info where class > 2
2> go
name	class	age	hight
小红	6	35	130
小兵	3	25	234
(2 rows affected)
1> quit
[root@localhost ~]# 

可以看到,4.2 和 7.0 两个版本都是可以使用的。


6.C++代码的整改

这部分说明是在《FreeTDS库文件在C++代码中的简单应用》中代码的基础进行修改的。

  • 第一种方式:在代码中设置FreeTDS的版本

    bool Ftds_Connect_DB(const char* const szUser,
    const char* const szPwd,
    const char* const szSvr,
    const char* const szDb)
    {
    if (!Init_DB())
    {
    return false;
    }

      LOGINREC *loginrec; //数据库连接对象
    
      // Create database connection object
      loginrec=dblogin();
      	
      // Set the login user name
      DBSETLUSER(loginrec,szUser);
      
      // Set the login password
      DBSETLPWD(loginrec,szPwd);
    
      //设置FreeTDS版本号要在打开数据库API之前
      //使用下面的方法
      DBSETLVERSION(loginrec, DBVERSION_70);
      
      // Connect SQL server server address and port, here is the connection
      dbprocess = dbopen(loginrec, szSvr);
      if(dbprocess == FAIL)
      {
      	return false;
      }
      
      // 连接数据库
      if(dbuse(dbprocess, szDb)==FAIL)
      {
      	printf("Open data basename fail!...");
      	return false;
      }
      	
      return true;
    

    }

由上可以看到需要在打开数据库方法之前,增加 DBSETLVERSION(loginrec, DBVERSION_70) 方法。

  • 第二种方式:修改数据库连接信息,使用别名

    int DB_Test(void)
    {
    bool isconnectok = Ftds_Connect_DB("sa", "123456", "myWin130", "fy2000");
    if (!isconnectok)
    {
    printf("database connect fail...\n");
    }

    ========此处省略部分代码=========<<<<<<<<<<<<<<<<<<<<
    return 0;
    }

可以看到上面在方法 Ftds_Connect_DB 的第三个参数传入的是在 freetds.conf 中配置的别名。


以上就是本次分享的全部内容,希望对你有帮助,感谢您的查阅。

相关推荐
羱滒8 分钟前
sql调优之数据库开发规范
java·数据库·数据库开发
程序员Android11 分钟前
MTK多帧拍照流程分析
数据库
likfishdn11 分钟前
Linux的文件与目录管理
linux·运维·服务器
不剪发的Tony老师12 分钟前
Apache Doris:一款高性能的实时数据仓库
数据库·数据仓库
2501_9032386522 分钟前
Git Bash:Windows下的强大命令行工具
windows·git·bash·个人开发
甜可儿23 分钟前
redis序列化设置
数据库·redis
GGBondlctrl28 分钟前
【SpringBoot】论坛项目中如何进行实现发布文章,以及更新对应数据库的数据更新
数据库·springboot项目·三层设计思想·文章发布项目
chian-ocean31 分钟前
Linux 文件缓冲区:高效数据访问的幕后推手
linux·运维·服务器
加油=^_^=33 分钟前
【Linux】进程优先级 | 进程调度(三)
linux·运维·服务器
若云止水42 分钟前
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_init_cycle 函数 - 详解(4)
数据库·nginx·ubuntu