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 中配置的别名。


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

相关推荐
小安运维日记9 分钟前
Linux云计算 |【第四阶段】NOSQL-DAY1
linux·运维·redis·sql·云计算·nosql
kejijianwen1 小时前
JdbcTemplate常用方法一览AG网页参数绑定与数据寻址实操
服务器·数据库·oracle
编程零零七1 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
CoolTiger、3 小时前
【Vmware16安装教程】
linux·虚拟机·vmware16
学习3人组4 小时前
CentOS 中配置 OpenJDK以及多版本管理
linux·运维·centos
高兴就好(石4 小时前
DB-GPT部署和试用
数据库·gpt
厨 神5 小时前
vmware中的ubuntu系统扩容分区
linux·运维·ubuntu
这孩子叫逆5 小时前
6. 什么是MySQL的事务?如何在Java中使用Connection接口管理事务?
数据库·mysql
Karoku0665 小时前
【网站架构部署与优化】web服务与http协议
linux·运维·服务器·数据库·http·架构
geek_Chen015 小时前
虚拟机共享文件夹开启后mnt/hgfs/下无sharefiles? --已解决
linux·运维·服务器