sp_msforeachdb的替代方法

时间:2019-03-11 16:27:27

标签: sql-server

我继承了下面的脚本,并努力在不同实例的所有数据库上运行该脚本。当我使用sp_msforeachdb时它可以工作,但它不会以我想要的方式输出,它还为没有数据的数据库提供了空白结果集,这是使用sp_msforeachdb问题的一部分...我觉得这是我尝试过的联接不同的形式,但仍然没有输出我想要的方式。请查看并提供反馈。

SET NOCOUNT ON
declare @cmd1 nvarchar(2000)
set @cmd1 =
'use ?;
SELECT ''?''
       DatabaseName,
       [File Name],
       [Physical Name],
       [File - Total Size In MB],
       [File - Available Space In MB],
       [Filegroup Name],
       [Disk Mount Point],
       [Disk Total Size in GB],
       [Disk Available Size in GB],
       [Disk Free Space % ],
       Growth,
       NextGrowthRequirementInMB,
       FileSpaceAfterGrowthMB 
    FROM
       (
          SELECT
             DB_NAME() AS DatabaseName,
             f.[file_id],
             f.name AS [File Name],
             f.physical_name AS [Physical Name],
             CAST((f.size / 128.0) AS DECIMAL(15, 2)) AS [File - Total Size In MB],
             CAST(f.size / 128.0 - CAST(FILEPROPERTY(f.name, 'SpaceUsed') AS int) / 128.0 AS DECIMAL(15, 2)) AS [File - Available Space In MB],
             fg.name AS [Filegroup Name],
             volume_mount_point [Disk Mount Point],
             CONVERT(DECIMAL(18, 2), total_bytes / 1073741824.0) AS [Disk Total Size in GB],
             ---1GB = 1073741824 bytes CONVERT(DECIMAL(18,2),available_bytes/1073741824.0) AS [Disk Available Size in GB], 
             CAST(CAST(available_bytes AS FLOAT) / CAST(total_bytes AS FLOAT) AS DECIMAL(18, 2)) * 100 AS [Disk Free Space % ],
             f.Growth,
             CASE
                f.is_percent_growth 
                WHEN
                   0 
                THEN
                   f.Growth / 128 
                WHEN
                   1 
                THEN
                   f.growth / 100.00*CAST((f.size / 128.0) AS DECIMAL(15, 2)) 
             END
             AS NextGrowthRequirementInMB, CONVERT(DECIMAL(18, 2), total_bytes / 1073741824.0) - (
             CASE
                f.is_percent_growth 
                WHEN
                   0 
                THEN
                   f.Growth / 128 
                WHEN
                   1 
                THEN
                   f.growth / 100.00*CAST((f.size / 128.0) AS DECIMAL(15, 2)) 
             END
    ) AS FileSpaceAfterGrowthMB, f.is_percent_growth, file_system_type [File System Type] 
          FROM
             sys.database_files AS f WITH (NOLOCK) 
             INNER JOIN
                sys.master_files m 
                on f.file_id = m.file_id 
             LEFT OUTER JOIN
                sys.data_spaces AS fg WITH (NOLOCK) 
                ON f.data_space_id = fg.data_space_id CROSS APPLY sys.dm_os_volume_stats(database_id, m.file_id) 
          WHERE
             m.database_id = DB_ID()) a
where DB_NAME() NOT IN(''master'',''model'',''msdb'',''tempdb'',''xx'',''xxx'',''xxxx'')
     ORDER BY 1 desc'
EXEC sp_foreachdb @command = @cmd1
GO

2 个答案:

答案 0 :(得分:0)

删除USE ?;之后的分号,这就是为什么总是从同一数据库获取结果的原因。

要排除系统表,sp_foreachdb已经有一个名为@user_only的参数,您不需要在末尾添加

此外,您的查询大于2000个字符

SET NOCOUNT ON
declare @cmd1 nvarchar(max)
DROP TABLE #TMP
CREATE TABLE #TMP (DatabaseName VARCHAR(100),
       [File Name] VARCHAR(200),
       [Physical Name] VARCHAR(200),
       [File - Total Size In MB] FLOAT,
       [File - Available Space In MB] FLOAT,
       [Filegroup Name] VARCHAR(50),
       [Disk Mount Point]  VARCHAR(50),
       [Disk Total Size in GB] FLOAT,
       [Disk Available Size in GB] FLOAT,
       [Disk Free Space % ] FLOAT,
       Growth FLOAT,
       NextGrowthRequirementInMB FLOAT,
       FileSpaceAfterGrowthMB FLOAT)
set @cmd1 =
'use ?
INSERT #TMP
SELECT 
       DatabaseName,
       [File Name],
       [Physical Name],
       [File - Total Size In MB],
       [File - Available Space In MB],
       [Filegroup Name],
       [Disk Mount Point],
       [Disk Total Size in GB],
       [Disk Available Size in GB],
       [Disk Free Space % ],
       Growth,
       NextGrowthRequirementInMB,
       FileSpaceAfterGrowthMB 
    FROM
       (
          SELECT
             DB_NAME() AS DatabaseName,
             f.[file_id],
             f.name AS [File Name],
             f.physical_name AS [Physical Name],
             CAST((f.size / 128.0) AS DECIMAL(15, 2)) AS [File - Total Size In MB],
             CAST(f.size / 128.0 - CAST(FILEPROPERTY(f.name, ''SpaceUsed'') AS int) / 128.0 AS DECIMAL(15, 2)) AS [File - Available Space In MB],
             fg.name AS [Filegroup Name],
             volume_mount_point [Disk Mount Point],
             CONVERT(DECIMAL(18, 2), total_bytes / 1073741824.0) AS [Disk Total Size in GB],
             ---1GB = 1073741824 bytes 
             CONVERT(DECIMAL(18,2),available_bytes/1073741824.0) AS [Disk Available Size in GB], 
             CAST(CAST(available_bytes AS FLOAT) / CAST(total_bytes AS FLOAT) AS DECIMAL(18, 2)) * 100 AS [Disk Free Space % ],
             f.Growth,
             CASE
                f.is_percent_growth 
                WHEN
                   0 
                THEN
                   f.Growth / 128 
                WHEN
                   1 
                THEN
                   f.growth / 100.00*CAST((f.size / 128.0) AS DECIMAL(15, 2)) 
             END
             AS NextGrowthRequirementInMB, CONVERT(DECIMAL(18, 2), total_bytes / 1073741824.0) - (
             CASE
                f.is_percent_growth 
                WHEN
                   0 
                THEN
                   f.Growth / 128 
                WHEN
                   1 
                THEN
                   f.growth / 100.00*CAST((f.size / 128.0) AS DECIMAL(15, 2)) 
             END
    ) AS FileSpaceAfterGrowthMB, f.is_percent_growth, file_system_type [File System Type] 
          FROM
             sys.database_files AS f WITH (NOLOCK) 
             INNER JOIN
                sys.master_files m 
                on f.file_id = m.file_id 
             LEFT OUTER JOIN
                sys.data_spaces AS fg WITH (NOLOCK) 
                ON f.data_space_id = fg.data_space_id CROSS APPLY sys.dm_os_volume_stats(database_id, m.file_id) 
          WHERE
             m.database_id = DB_ID()) a' 




     EXEC sp_foreachdb @command = @cmd1, @user_only = 1
     SELECT * 
     FROM #TMP

答案 1 :(得分:0)

Below is the script with some additions but now unable to insert the output into a 
table.



SET NOCOUNT ON
declare @cmd1 nvarchar(max)
IF OBJECT_ID('tempdb..#TMP') IS NOT NULL
DROP TABLE #TMP

CREATE TABLE #TMP (
    [CheckDate] datetime,
    [DatabaseName] VARCHAR(100),
   [File Name] VARCHAR(200),
   [Physical Name] VARCHAR(200),
   [File - Total Size In MB] FLOAT,
   [File - Available Space In MB] FLOAT,
   [Filegroup Name] VARCHAR(50),
   [Disk Mount Point]  VARCHAR(50),
   [Disk Total Size in GB] FLOAT,
   [Disk Available Size in GB] FLOAT,
   [Disk Free Space % ] FLOAT,
   Growth FLOAT,
   NextGrowthRequirementInMB FLOAT,
   FileSpaceAfterGrowthMB FLOAT)
set @cmd1 =
'use ?
INSERT #TMP
SELECT 
    [CheckDate],
   [DatabaseName],
   [File Name],
   [Physical Name],
   [File - Total Size In MB],
   [File - Available Space In MB],
   [Filegroup Name],
   [Disk Mount Point],
   [Disk Total Size in GB],
   [Disk Available Size in GB],
   [Disk Free Space % ],
   Growth,
   NextGrowthRequirementInMB,
   FileSpaceAfterGrowthMB 
FROM
   (
      SELECT
CONVERT(VARCHAR(24),GETDATE(),121) [CheckDate],
         DB_NAME() AS DatabaseName,
         f.[file_id],
         f.name AS [File Name],
         f.physical_name AS [Physical Name],
         CAST((f.size / 128.0) AS DECIMAL(15, 2)) AS [File - Total Size In MB],
         CAST(f.size / 128.0 - CAST(FILEPROPERTY(f.name, ''SpaceUsed'') AS int) / 
128.0 AS DECIMAL(15, 2)) AS [File - Available Space In MB],
         fg.name AS [Filegroup Name],
         volume_mount_point [Disk Mount Point],
         CONVERT(DECIMAL(18, 2), total_bytes / 1073741824.0) AS [Disk Total Size in 
GB],
         ---1GB = 1073741824 bytes 
         CONVERT(DECIMAL(18,2),available_bytes/1073741824.0) AS [Disk Available Size 
in GB], 
         CAST(CAST(available_bytes AS FLOAT) / CAST(total_bytes AS FLOAT) AS 
DECIMAL(18, 2)) * 100 AS [Disk Free Space % ],
         f.Growth,
         CASE
            f.is_percent_growth 
            WHEN
               0 
            THEN
               f.Growth / 128 
            WHEN
               1 
            THEN
               f.growth / 100.00*CAST((f.size / 128.0) AS DECIMAL(15, 2)) 
         END
         AS NextGrowthRequirementInMB, CONVERT(DECIMAL(18, 2), total_bytes / 
1073741824.0) - (
         CASE
            f.is_percent_growth 
            WHEN
               0 
            THEN
               f.Growth / 128 
            WHEN
               1 
            THEN
               f.growth / 100.00*CAST((f.size / 128.0) AS DECIMAL(15, 2)) 
         END
) AS FileSpaceAfterGrowthMB, f.is_percent_growth, file_system_type [File System Type] 
      FROM
         sys.database_files AS f WITH (NOLOCK) 
         INNER JOIN
            sys.master_files m 
            on f.file_id = m.file_id 
         LEFT OUTER JOIN
            sys.data_spaces AS fg WITH (NOLOCK) 
            ON f.data_space_id = fg.data_space_id CROSS APPLY 
sys.dm_os_volume_stats(database_id, m.file_id) 
      WHERE
         m.database_id = DB_ID()) a
ORDER BY 7 desc' 

 EXEC sp_foreachdb @command = @cmd1, @user_only = 1, @exclude_list = '', 
@is_read_only =
NULL
SET NOCOUNT OFF
 SELECT * FROM #TMP