问题描述
我正在使用 dotnetcore 1.1
并尝试连接到 SQL 服务器版本 8.00.2055
.
I am using dotnetcore 1.1
and trying to connect to SQL server version 8.00.2055
.
我在项目中有 2 个连接:一个到 SqlServer 2016,另一个到 Sql Server 8.00.2055
(Sql Server 2000?)
I have 2 connections inside project: one to SqlServer 2016 and another one to Sql Server 8.00.2055
(Sql Server 2000?)
无法建立第二个连接.这是我得到的错误:
This second connection could not be established. Here is the error I am getting:
2017-07-31T11:34:24.8747442+02:00 0HL6NUT8S82KF [ERR] 用户:- SQL Server 实例在登录协商期间返回了无效或不受支持的协议版本.(637b11d7)
2017-07-31T11:34:24.8747442+02:00 0HL6NUT8S82KF [ERR] User : - The SQL Server instance returned an invalid or unsupported protocol version during login negotiation. (637b11d7)
我使用的连接字符串是 Server=MyServerHost;初始目录=MyDatabaseName;用户 id=sa;密码=********;
Connection String I am using is Server=MyServerHost; Initial Catalog=MyDatabaseName; User id=sa; Password=********;
知道如何解决这个错误吗?
Any idea how to fix this error?
推荐答案
.NET Core 不支持低于 SQL Server 2005 的 SQL Server 版本.或者说,它不支持低于 TDS 7.2(引入的版本)的 TDS 协议版本由 SQL Server 2005).来源:
.NET Core does not support SQL Server versions lower than SQL Server 2005. Or rather, it does not support TDS protocol versions lower than TDS 7.2 (the version introduced by SQL Server 2005). The relevant bit of source:
a.tdsVersion = (UInt32)((((((b[0] << 8) | b[1]) << 8) | b[2]) << 8) | b[3]); // bytes are in motorola order (high byte first)
UInt32 majorMinor = a.tdsVersion & 0xff00ffff;
UInt32 increment = (a.tdsVersion >> 16) & 0xff;
// Server responds:
// 0x07000000 -> Sphinx // Notice server response format is different for bwd compat
// 0x07010000 -> Shiloh RTM // Notice server response format is different for bwd compat
// 0x71000001 -> Shiloh SP1
// 0x72xx0002 -> Yukon RTM
// information provided by S. Ashwin
switch (majorMinor)
{
case TdsEnums.YUKON_MAJOR << 24 | TdsEnums.YUKON_RTM_MINOR: // Yukon
if (increment != TdsEnums.YUKON_INCREMENT) { throw SQL.InvalidTDSVersion(); }
_isYukon = true;
break;
case TdsEnums.KATMAI_MAJOR << 24 | TdsEnums.KATMAI_MINOR:
if (increment != TdsEnums.KATMAI_INCREMENT) { throw SQL.InvalidTDSVersion(); }
_isKatmai = true;
break;
case TdsEnums.DENALI_MAJOR << 24 | TdsEnums.DENALI_MINOR:
if (increment != TdsEnums.DENALI_INCREMENT) { throw SQL.InvalidTDSVersion(); }
_isDenali = true;
break;
default:
throw SQL.InvalidTDSVersion();
}
供参考:Sphinx 是 7.0,Shiloh 是 2000,Yukon 是 2005,Katmai 是 2008,Denali 是 2012(这些是代号).这些名称具有误导性,因为此处验证的版本是 TDS 协议版本,而不是 SQL Server 版本.SQL Server 2012、2014 和 2016 都使用 TDS 7.4(根据 此参考a>),这就是为什么除了 Denali 之外没有检查.
For reference: Sphinx is 7.0, Shiloh is 2000, Yukon is 2005, Katmai is 2008, Denali is 2012 (these are the code names). These names are misleading because the version verified here is the TDS protocol version, not the SQL Server version. SQL Server 2012, 2014 and 2016 all use TDS 7.4 (per this reference), which is why there are no checks beyond Denali.
这是 参考中的同一段代码.NET 框架的来源:
a.tdsVersion = (UInt32)((((((b[0]<<8)|b[1])<<8)|b[2])<<8)|b[3]); // bytes are in motorola order (high byte first)
UInt32 majorMinor = a.tdsVersion & 0xff00ffff;
UInt32 increment = (a.tdsVersion >> 16) & 0xff;
// Server responds:
// 0x07000000 -> Sphinx // Notice server response format is different for bwd compat
// 0x07010000 -> Shiloh RTM // Notice server response format is different for bwd compat
// 0x71000001 -> Shiloh SP1
// 0x72xx0002 -> Yukon RTM
// information provided by S. Ashwin
switch (majorMinor) {
case TdsEnums.SPHINXORSHILOH_MAJOR<<24|TdsEnums.DEFAULT_MINOR: // Sphinx & Shiloh RTM
// note that sphinx and shiloh_rtm can only be distinguished by the increment
switch (increment) {
case TdsEnums.SHILOH_INCREMENT:
_isShiloh = true;
break;
case TdsEnums.SPHINX_INCREMENT:
// no flag will be set
break;
default:
throw SQL.InvalidTDSVersion();
}
break;
case TdsEnums.SHILOHSP1_MAJOR<<24|TdsEnums.SHILOHSP1_MINOR: // Shiloh SP1
if (increment != TdsEnums.SHILOHSP1_INCREMENT) { throw SQL.InvalidTDSVersion(); }
_isShilohSP1 = true;
break;
case TdsEnums.YUKON_MAJOR<<24|TdsEnums.YUKON_RTM_MINOR: // Yukon
if (increment != TdsEnums.YUKON_INCREMENT) { throw SQL.InvalidTDSVersion(); }
_isYukon = true;
break;
case TdsEnums.KATMAI_MAJOR<<24|TdsEnums.KATMAI_MINOR:
if (increment != TdsEnums.KATMAI_INCREMENT) { throw SQL.InvalidTDSVersion(); }
_isKatmai = true;
break;
case TdsEnums.DENALI_MAJOR << 24|TdsEnums.DENALI_MINOR:
if (increment != TdsEnums.DENALI_INCREMENT) { throw SQL.InvalidTDSVersion(); }
_isDenali = true;
break;
default:
throw SQL.InvalidTDSVersion();
}
对 TDS 7.0 和 7.1 的支持清晰可见.
Support for TDS 7.0 and 7.1 is clearly visible.
我在网上找不到关于在 .NET Core 中不支持任何低于 SQL Server 2005 的决定的信息,并且在最早的提交中(从 2015 年 9 月开始)已经存在缺乏支持的情况.鉴于自 2013 年以来 SQL Server 2000 已停止扩展支持,这并非没有道理.
I couldn't find information online on the decision not to support anything lower than SQL Server 2005 in .NET Core and the lack of support is already present in the earliest commit (from September 2015). Given that SQL Server 2000 has been out of extended support since 2013, this is not unreasonable.
简而言之:要么坚持使用完整的 .NET Framework(尚未(尚未)放弃对 SQL Server 2000 的支持),要么升级您的服务器(强烈建议).可以想象,您也可以分叉代码以将 SQL Server 2000 支持向后移植到 .NET Core,但这几乎肯定不值得付出努力.
In short: either stick to using the full .NET Framework (which has not (yet) dropped support for SQL Server 2000), or upgrade your server (highly advisable). Conceivably, you could also fork the code to backport SQL Server 2000 support to .NET Core, but this is almost certainly not worth the effort.
这篇关于SQL Server 实例在登录协商期间返回无效或不受支持的协议版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!