MSSQL中SERVERPROPERTY('ProductVersion')读取失败致版本检查异常求助
使用SERVERPROPERTY('ProductVersion')校验SQL Server版本时的高负载异常问题
我通过SERVERPROPERTY('ProductVersion')属性进行SQL Server版本校验,根据返回值执行对应动态脚本,代码如下:
DECLARE @query NVARCHAR(MAX) DECLARE @version NVARCHAR(128) = CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR) SET @version = SUBSTRING(@version, 1, CHARINDEX('.', @version) - 1) DECLARE @versionAsInt INT = CAST(@version AS INT) IF @versionAsInt > 10 SET @query = 'SELECT 1' ELSE SET @query = 'SELECT 2' EXEC sp_executesql @query
但在服务器高负载时,该校验偶尔会失败,执行了与已安装版本不匹配的代码引发错误,种种迹象表明SERVERPROPERTY('ProductVersion')有时会返回null。想知道是否有人遇到过类似问题,以及对应的解决办法。
解决方案与说明
- 确实有不少用户在高负载场景下遇到
SERVERPROPERTY('ProductVersion')返回null的情况,这是因为SQL Server资源紧张时,无法及时读取系统内部的版本元数据。 - 可以通过以下方式优化代码,避免异常:
1. 增加null值兜底逻辑,使用@@VERSION作为备选
@@VERSION返回的字符串包含更多信息,但它读取的是预缓存的系统数据,在高负载下稳定性更高,很少返回null。修改后的代码示例:
DECLARE @query NVARCHAR(MAX) DECLARE @version NVARCHAR(128) = CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR) -- 当SERVERPROPERTY返回null时,用@@VERSION提取版本号 IF @version IS NULL BEGIN -- 从@@VERSION中提取数字开头的版本号部分 SET @version = SUBSTRING(@@VERSION, PATINDEX('%[0-9]%', @@VERSION), LEN(@@VERSION)) SET @version = LEFT(@version, CHARINDEX('.', @version) - 1) END ELSE BEGIN SET @version = SUBSTRING(@version, 1, CHARINDEX('.', @version) - 1) END -- 使用TRY_CAST避免转换失败抛出异常 DECLARE @versionAsInt INT = TRY_CAST(@version AS INT) -- 处理转换失败的情况,设置默认分支 IF @versionAsInt IS NULL OR @versionAsInt > 10 SET @query = 'SELECT 1' ELSE SET @query = 'SELECT 2' EXEC sp_executesql @query
2. 使用TRY_CAST替代CAST,避免转换异常
即使版本字符串获取出现问题,TRY_CAST会返回null而不是抛出错误,方便后续做默认分支处理。
3. 高负载场景下优先使用@@VERSION
如果服务器经常处于高负载状态,可以直接使用@@VERSION来提取版本号,跳过SERVERPROPERTY的调用,进一步提升稳定性。
内容的提问来源于stack exchange,提问作者MiXaiL
相关产品推荐
相关产品推荐

