提示 \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.0A typical Microsoft server
[egServer73]
host = ntmachine.domain.com
port = 1433
tds version = 7.3The 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 中配置的别名。