SQL 查询多台服务器失败

SQL query to multiple servers fails

我尝试 运行 此查询针对多个已注册 SQL 使用 SSMS 的服务器:

SELECT DISTINCT(volume_mount_point), 
    total_bytes / 1048576 AS Size_in_MB, 
    available_bytes / 1048576 AS Free_in_MB,
    (SELECT ROUND(CAST(available_bytes / 1048576 * 1.0 as FLOAT) / CAST(total_bytes / 1048576 * 1.0 AS FLOAT) * 100, 2)) AS FreePercentage
FROM 
    sys.master_files AS f 
CROSS APPLY 
    sys.dm_os_volume_stats(f.database_id, f.file_id)
GROUP BY
    volume_mount_point, total_bytes / 1048576, available_bytes / 1048576  
ORDER BY 
    4

一些服务器有 SQL 不知道的 Server 2008 R2 RTM 产品级别 "sys.dm_os_volume_stats" 和整个查询崩溃报告:

Msg 208, Level 16, State 1, Line 1
Invalid object name 'sys.dm_os_volume_stats'.

我尝试在主SELECT之前添加一个条件,但它不起作用:

  DECLARE @ProductLevel varchar(128)  
  SET @ProductLevel = CONVERT(VARCHAR(128), SERVERPROPERTY ('ProductLevel'))
  IF @ProductLevel not like 'RTM'
    BEGIN...

我也试过通过这个文档来区分结果 To change the multiserver results options

To change the multiserver results options In Management Studio, on the Tools menu, click Options.

Expand Query Results, expand SQL Server, and then click Multiserver Results.

On the Multiserver Results page, specify the option settings that you want, and then click OK.

还有其他想法吗?

如果 DMV 不存在,则不会评估 IF 条件,因为整个批处理在编译时失败,因此永远不会执行 IF 语句。

一种解决方法是将查询包装在条件动态 SQL:

IF CAST(PARSENAME(CAST(SERVERPROPERTY('ProductVersion') AS varchar(20)),4) AS int) > 10 OR 
    (CAST(PARSENAME(CAST(SERVERPROPERTY('ProductVersion') AS varchar(20)),4) AS int) = 10
     AND CAST(PARSENAME(CAST(SERVERPROPERTY('ProductVersion') AS varchar(20)),3) AS int) = 5
     AND SERVERPROPERTY('ProductLevel') <> 'RTM')
BEGIN
EXEC sp_executesql N'
SELECT DISTINCT(volume_mount_point), 
    total_bytes / 1048576 AS Size_in_MB, 
    available_bytes / 1048576 AS Free_in_MB,
    (SELECT ROUND(CAST(available_bytes / 1048576 * 1.0 as FLOAT) / CAST(total_bytes / 1048576 * 1.0 AS FLOAT) * 100, 2)) AS FreePercentage
FROM 
    sys.master_files AS f 
CROSS APPLY 
    sys.dm_os_volume_stats(f.database_id, f.file_id)
GROUP BY
    volume_mount_point, total_bytes / 1048576, available_bytes / 1048576  
ORDER BY 
    4;
'
END;