SQL-запрос к нескольким серверам завершается неудачно - PullRequest
1 голос
/ 12 мая 2019

Я пытаюсь выполнить этот запрос для нескольких зарегистрированных 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", и отчет о сбоях всего запроса:

Сообщение 208, Уровень 16, Состояние 1, Строка 1
Неверное имя объекта 'sys.dm_os_volume_stats'.

Я пытался добавить условие перед основным SELECT, но оно не работает:

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

Я также пытался разделить результаты по этой документации Чтобы изменить параметры результатов мультисервера

Чтобы изменить параметры результатов на нескольких серверах В Management Studio на В меню Сервис выберите пункт Параметры.

Разверните Результаты запроса, разверните SQL Server и затем щелкните Мультисервер. Результаты.

На странице результатов Multiserver укажите настройки параметров, которые вы хотите, а затем нажмите кнопку ОК.

Есть еще идеи?

1 Ответ

1 голос
/ 13 мая 2019

Условие IF не будет оцениваться, если DMV не существует, поскольку весь пакет завершается с ошибкой во время компиляции, поэтому оператор 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;
...