2017-04-06 109 views
-1

下面的腳本的目的是從每臺服務器收集數據庫大小和數據庫數量的總和,然後總計總和。動態SQL中的UNION - TSQL

DECLARE @LinkedServer VARCHAR(100) 
DECLARE @SQL1   NVARCHAR(MAX) 
DECLARE @SQL2   NVARCHAR(MAX) 
DECLARE @TotalDB  NVARCHAR(1000) 
DECLARE @TotalSize  NVARCHAR(1000) 
DECLARE @LineSpace  VARCHAR(100) 
DECLARE @Union1   VARCHAR(200) 
DECLARE @Union2   VARCHAR(200) 

SELECT @LinkedServer = MIN(name) 
    FROM ServerwithLinkedServers.master.sys.servers 
    WHERE name IN ('ServerName1', 
        'ServerName2', 
        'ServerName3') 

WHILE @LinkedServer IS NOT NULL 

    BEGIN 
     SET @TotalDB = 'SELECT COUNT(*) AS [Total Retailer Databases] FROM '+ @LinkedServer +'.master.sys.databases'; 
     SET @Union1 = @TotalDB + ' UNION ' + @TotalDB; 
     SET @TotalSize = 'SELECT CAST(SUM(size) * 8.00/1024.00/1024.00 AS DECIMAL(9,2)) AS [Total Size GB] FROM '+ @LinkedServer +'.master.sys.master_files'; 
     SET @Union2 = @TotalSize + ' UNION ' + @TotalSize; 

     EXEC (@Union1); 
     EXEC (@Union2); 

     SELECT @LinkedServer = MIN(name) 
      FROM ServerwithLinkedServers.master.sys.servers 
      WHERE name IN ('ServerName1', 
          'ServerName2', 
          'ServerName3') 
       AND name > @LinkedServer 
    END 

    print @union1 
    print @union2 

然而,當我執行我得到一個錯誤,說明代碼:

Unclosed quotation mark after the character string 'T'. 
Incorrect syntax near 'T'. 

我缺少什麼?或者我做錯了什麼?

+2

打印您的語句而不是執行 - 並檢查它。錯誤信息清楚地表明 - 您在某處錯過了引號。 –

+2

你爲什麼在這裏循環?從遠程系統提取數據有什麼意義?無論如何,您已經硬編碼了這些值,所以在閱讀服務器列表時除了其中一個已經從遠程服務器上刪除以外,沒有任何意義。然後你從每個服務器獲得兩次數據庫的數量。這整個事情可以重寫沒有循環很容易,但我不明白它想要做什麼。 –

+0

我需要硬編碼的ServerNames,因爲一些鏈接的服務器不再工作了(某些服務器已經退役)。該腳本假設檢索每臺服務器的數據庫數量,同時獲取大小。和所有聯合在一起的總和。我將如何重寫這個腳本而不使用循環? – AznDevil92

回答

1

下面介紹如何在不使用循環的情況下利用動態sql來處理這類事情。我還將您的查詢重新編寫爲每個數據庫的單個查詢。這將返回每臺服務器上的數據庫數量以及這些文件使用的總空間量。我建議調整這一點,以排除像master,tempdb,模型等某些數據庫...

這將仍然會返回整個列表,但不需要循環。一旦你熟悉它生成的動態sql,你可以註釋掉該行並取消註釋exec行。

DECLARE @SQL NVARCHAR(MAX) = '' 

SELECT @SQL = @SQL + 'select count(distinct d.database_id) as TotalRetailerDatabases 
    , CAST(SUM(size) * 8.00/1024.00/1024.00 AS DECIMAL(9,2)) TotalSizeGB 
from ' + name + '.sys.master_files mf 
join ' + name + '.master.sys.databases d on d.database_id = mf.database_id UNION ALL ' 
FROM ServerwithLinkedServers.master.sys.servers 
WHERE name IN 
(
    'ServerName1' 
    , 'ServerName2' 
    , 'ServerName3' 
) 

set @SQL = left(@SQL, len(@SQL) - 10) --remove the last UNION ALL 

select @SQL 
--exec sp_executesql @SQL1 
+0

刪除最後一個UNION ALL是什麼意思? – AznDevil92

+0

查看未刪除最後10個字符而創建的字符串,它將有一個尾隨UNION ALL。 :)很高興這爲你工作。 –

0

由於我在查詢中沒有看到T,所以我必須假設你有一個帶有T的ServerName,後跟一個空格。

嘗試在您的查詢中使用QUOTENAME(@LinkedServer)無處不在@LinkedServer