提示 \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.20240410freetds.conf directory: /usr/local/etcMS db-lib source compatibility: yesSybase binary compatibility: noThread safety: yesiconv library: yesTDS version: 7.4iODBC: nounixodbc: yesSSPI "trusted" logins: noKerberos: noOpenSSL: yesGnuTLS: noMARS: 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 versiontds version = auto
>>>>>>>>>>>>>>>=======[此处省略了global下的部分内容]=======<<<<<<<<<<<<<<<<<<<<<<# A typical Sybase server
[egServer50]host = symachine.domain.comport = 5000tds version = 5.0# A typical Microsoft server
[egServer73]host = ntmachine.domain.comport = 1433tds version = 7.3# The server you added yourself
[myWin130]host = 192.168.1.130port = 1433tds 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.130port = 1433tds 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.130port = 1433tds 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 objectloginrec=dblogin();// Set the login user nameDBSETLUSER(loginrec,szUser);// Set the login passwordDBSETLPWD(loginrec,szPwd);//设置FreeTDS版本号要在打开数据库API之前//使用下面的方法DBSETLVERSION(loginrec, DBVERSION_70);// Connect SQL server server address and port, here is the connectiondbprocess = 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 中配置的别名。