2008-08-16 12 views

Respuesta

6

Fuente: http://searchsqlserver.techtarget.com/tip/0,289483,sid87_gci1313431,00.html Funciona con SQL2000,2005,2008

USE master; 
GO 

IF OBJECT_ID('dbo.sp_SDS', 'P') IS NOT NULL 
    DROP PROCEDURE dbo.sp_SDS; 
GO 

CREATE PROCEDURE dbo.sp_SDS 
    @TargetDatabase sysname = NULL,  -- NULL: all dbs 
    @Level varchar(10) = 'Database', -- or "File" 
    @UpdateUsage bit = 0,    -- default no update 
    @Unit char(2) = 'MB'    -- Megabytes, Kilobytes or Gigabytes 
AS 

/************************************************************************************************** 
** 
** author: Richard Ding 
** date: 4/8/2008 
** usage: list db size AND path w/o SUMmary 
** test code: sp_SDS -- default behavior 
**    sp_SDS 'maAster' 
**    sp_SDS NULL, NULL, 0 
**    sp_SDS NULL, 'file', 1, 'GB' 
**    sp_SDS 'Test_snapshot', 'Database', 1 
**    sp_SDS 'Test', 'File', 0, 'kb' 
**    sp_SDS 'pfaids', 'Database', 0, 'gb' 
**    sp_SDS 'tempdb', NULL, 1, 'kb' 
** 
**************************************************************************************************/ 

SET NOCOUNT ON; 

IF @TargetDatabase IS NOT NULL AND DB_ID(@TargetDatabase) IS NULL 
    BEGIN 
    RAISERROR(15010, -1, -1, @TargetDatabase); 
    RETURN (-1) 
    END 

IF OBJECT_ID('tempdb.dbo.##Tbl_CombinedInfo', 'U') IS NOT NULL 
    DROP TABLE dbo.##Tbl_CombinedInfo; 

IF OBJECT_ID('tempdb.dbo.##Tbl_DbFileStats', 'U') IS NOT NULL 
    DROP TABLE dbo.##Tbl_DbFileStats; 

IF OBJECT_ID('tempdb.dbo.##Tbl_ValidDbs', 'U') IS NOT NULL 
    DROP TABLE dbo.##Tbl_ValidDbs; 

IF OBJECT_ID('tempdb.dbo.##Tbl_Logs', 'U') IS NOT NULL 
    DROP TABLE dbo.##Tbl_Logs; 

CREATE TABLE dbo.##Tbl_CombinedInfo (
    DatabaseName sysname NULL, 
    [type] VARCHAR(10) NULL, 
    LogicalName sysname NULL, 
    T dec(10, 2) NULL, 
    U dec(10, 2) NULL, 
    [U(%)] dec(5, 2) NULL, 
    F dec(10, 2) NULL, 
    [F(%)] dec(5, 2) NULL, 
    PhysicalName sysname NULL); 

CREATE TABLE dbo.##Tbl_DbFileStats (
    Id int identity, 
    DatabaseName sysname NULL, 
    FileId int NULL, 
    FileGroup int NULL, 
    TotalExtents bigint NULL, 
    UsedExtents bigint NULL, 
    Name sysname NULL, 
    FileName varchar(255) NULL); 

CREATE TABLE dbo.##Tbl_ValidDbs (
    Id int identity, 
    Dbname sysname NULL); 

CREATE TABLE dbo.##Tbl_Logs (
    DatabaseName sysname NULL, 
    LogSize dec (10, 2) NULL, 
    LogSpaceUsedPercent dec (5, 2) NULL, 
    Status int NULL); 

DECLARE @Ver varchar(10), 
     @DatabaseName sysname, 
     @Ident_last int, 
     @String varchar(2000), 
     @BaseString varchar(2000); 

SELECT @DatabaseName = '', 
     @Ident_last = 0, 
     @String = '', 
     @Ver = CASE WHEN @@VERSION LIKE '%9.0%' THEN 'SQL 2005' 
        WHEN @@VERSION LIKE '%8.0%' THEN 'SQL 2000' 
        WHEN @@VERSION LIKE '%10.0%' THEN 'SQL 2008' 
       END; 

SELECT @BaseString = 
' SELECT DB_NAME(), ' + 
CASE WHEN @Ver = 'SQL 2000' THEN 'CASE WHEN status & 0x40 = 0x40 THEN ''Log'' ELSE ''Data'' END' 
    ELSE ' CASE type WHEN 0 THEN ''Data'' WHEN 1 THEN ''Log'' WHEN 4 THEN ''Full-text'' ELSE ''reserved'' END' END + 
', name, ' + 
CASE WHEN @Ver = 'SQL 2000' THEN 'filename' ELSE 'physical_name' END + 
', size*8.0/1024.0 FROM ' + 
CASE WHEN @Ver = 'SQL 2000' THEN 'sysfiles' ELSE 'sys.database_files' END + 
' WHERE ' 
+ CASE WHEN @Ver = 'SQL 2000' THEN ' HAS_DBACCESS(DB_NAME()) = 1' ELSE 'state_desc = ''ONLINE''' END + ''; 

SELECT @String = 'INSERT INTO dbo.##Tbl_ValidDbs SELECT name FROM ' + 
       CASE WHEN @Ver = 'SQL 2000' THEN 'master.dbo.sysdatabases' 
         WHEN @Ver IN ('SQL 2005', 'SQL 2008') THEN 'master.sys.databases' 
       END + ' WHERE HAS_DBACCESS(name) = 1 ORDER BY name ASC'; 
EXEC (@String); 

INSERT INTO dbo.##Tbl_Logs EXEC ('DBCC SQLPERF (LOGSPACE) WITH NO_INFOMSGS'); 

-- For data part 
IF @TargetDatabase IS NOT NULL 
    BEGIN 
    SELECT @DatabaseName = @TargetDatabase; 
    IF @UpdateUsage <> 0 AND DATABASEPROPERTYEX (@DatabaseName,'Status') = 'ONLINE' 
      AND DATABASEPROPERTYEX (@DatabaseName, 'Updateability') <> 'READ_ONLY' 
     BEGIN 
     SELECT @String = 'USE [' + @DatabaseName + '] DBCC UPDATEUSAGE (0)'; 
     PRINT '*** ' + @String + ' *** '; 
     EXEC (@String); 
     PRINT ''; 
     END 

    SELECT @String = 'INSERT INTO dbo.##Tbl_CombinedInfo (DatabaseName, type, LogicalName, PhysicalName, T) ' + @BaseString; 

    INSERT INTO dbo.##Tbl_DbFileStats (FileId, FileGroup, TotalExtents, UsedExtents, Name, FileName) 
      EXEC ('USE [' + @DatabaseName + '] DBCC SHOWFILESTATS WITH NO_INFOMSGS'); 
    EXEC ('USE [' + @DatabaseName + '] ' + @String); 

    UPDATE dbo.##Tbl_DbFileStats SET DatabaseName = @DatabaseName; 
    END 
ELSE 
    BEGIN 
    WHILE 1 = 1 
     BEGIN 
     SELECT TOP 1 @DatabaseName = Dbname FROM dbo.##Tbl_ValidDbs WHERE Dbname > @DatabaseName ORDER BY Dbname ASC; 
     IF @@ROWCOUNT = 0 
      BREAK; 
     IF @UpdateUsage <> 0 AND DATABASEPROPERTYEX (@DatabaseName, 'Status') = 'ONLINE' 
       AND DATABASEPROPERTYEX (@DatabaseName, 'Updateability') <> 'READ_ONLY' 
      BEGIN 
      SELECT @String = 'DBCC UPDATEUSAGE (''' + @DatabaseName + ''') '; 
      PRINT '*** ' + @String + '*** '; 
      EXEC (@String); 
      PRINT ''; 
      END 

     SELECT @Ident_last = ISNULL(MAX(Id), 0) FROM dbo.##Tbl_DbFileStats; 

     SELECT @String = 'INSERT INTO dbo.##Tbl_CombinedInfo (DatabaseName, type, LogicalName, PhysicalName, T) ' + @BaseString; 

     EXEC ('USE [' + @DatabaseName + '] ' + @String); 

     INSERT INTO dbo.##Tbl_DbFileStats (FileId, FileGroup, TotalExtents, UsedExtents, Name, FileName) 
      EXEC ('USE [' + @DatabaseName + '] DBCC SHOWFILESTATS WITH NO_INFOMSGS'); 

     UPDATE dbo.##Tbl_DbFileStats SET DatabaseName = @DatabaseName WHERE Id BETWEEN @Ident_last + 1 AND @@IDENTITY; 
     END 
    END 

-- set used size for data files, do not change total obtained from sys.database_files as it has for log files 
UPDATE dbo.##Tbl_CombinedInfo 
SET U = s.UsedExtents*8*8/1024.0 
FROM dbo.##Tbl_CombinedInfo t JOIN dbo.##Tbl_DbFileStats s 
ON t.LogicalName = s.Name AND s.DatabaseName = t.DatabaseName; 

-- set used size and % values for log files: 
UPDATE dbo.##Tbl_CombinedInfo 
SET [U(%)] = LogSpaceUsedPercent, 
U = T * LogSpaceUsedPercent/100.0 
FROM dbo.##Tbl_CombinedInfo t JOIN dbo.##Tbl_Logs l 
ON l.DatabaseName = t.DatabaseName 
WHERE t.type = 'Log'; 

UPDATE dbo.##Tbl_CombinedInfo SET F = T - U, [U(%)] = U*100.0/T; 

UPDATE dbo.##Tbl_CombinedInfo SET [F(%)] = F*100.0/T; 

IF UPPER(ISNULL(@Level, 'DATABASE')) = 'FILE' 
    BEGIN 
    IF @Unit = 'KB' 
     UPDATE dbo.##Tbl_CombinedInfo 
     SET T = T * 1024, U = U * 1024, F = F * 1024; 

    IF @Unit = 'GB' 
     UPDATE dbo.##Tbl_CombinedInfo 
     SET T = T/1024, U = U/1024, F = F/1024; 

    SELECT DatabaseName AS 'Database', 
     type AS 'Type', 
     LogicalName, 
     T AS 'Total', 
     U AS 'Used', 
     [U(%)] AS 'Used (%)', 
     F AS 'Free', 
     [F(%)] AS 'Free (%)', 
     PhysicalName 
     FROM dbo.##Tbl_CombinedInfo 
     WHERE DatabaseName LIKE ISNULL(@TargetDatabase, '%') 
     ORDER BY DatabaseName ASC, type ASC; 

    SELECT CASE WHEN @Unit = 'GB' THEN 'GB' WHEN @Unit = 'KB' THEN 'KB' ELSE 'MB' END AS 'SUM', 
     SUM (T) AS 'TOTAL', SUM (U) AS 'USED', SUM (F) AS 'FREE' FROM dbo.##Tbl_CombinedInfo; 
    END 

IF UPPER(ISNULL(@Level, 'DATABASE')) = 'DATABASE' 
    BEGIN 
    DECLARE @Tbl_Final TABLE (
     DatabaseName sysname NULL, 
     TOTAL dec (10, 2), 
     [=] char(1), 
     used dec (10, 2), 
     [used (%)] dec (5, 2), 
     [+] char(1), 
     free dec (10, 2), 
     [free (%)] dec (5, 2), 
     [==] char(2), 
     Data dec (10, 2), 
     Data_Used dec (10, 2), 
     [Data_Used (%)] dec (5, 2), 
     Data_Free dec (10, 2), 
     [Data_Free (%)] dec (5, 2), 
     [++] char(2), 
     Log dec (10, 2), 
     Log_Used dec (10, 2), 
     [Log_Used (%)] dec (5, 2), 
     Log_Free dec (10, 2), 
     [Log_Free (%)] dec (5, 2)); 

    INSERT INTO @Tbl_Final 
     SELECT x.DatabaseName, 
      x.Data + y.Log AS 'TOTAL', 
      '=' AS '=', 
      x.Data_Used + y.Log_Used AS 'U', 
      (x.Data_Used + y.Log_Used)*100.0/(x.Data + y.Log) AS 'U(%)', 
      '+' AS '+', 
      x.Data_Free + y.Log_Free AS 'F', 
      (x.Data_Free + y.Log_Free)*100.0/(x.Data + y.Log) AS 'F(%)', 
      '==' AS '==', 
      x.Data, 
      x.Data_Used, 
      x.Data_Used*100/x.Data AS 'D_U(%)', 
      x.Data_Free, 
      x.Data_Free*100/x.Data AS 'D_F(%)', 
      '++' AS '++', 
      y.Log, 
      y.Log_Used, 
      y.Log_Used*100/y.Log AS 'L_U(%)', 
      y.Log_Free, 
      y.Log_Free*100/y.Log AS 'L_F(%)' 
     FROM 
     (SELECT d.DatabaseName, 
       SUM(d.T) AS 'Data', 
       SUM(d.U) AS 'Data_Used', 
       SUM(d.F) AS 'Data_Free' 
      FROM dbo.##Tbl_CombinedInfo d WHERE d.type = 'Data' GROUP BY d.DatabaseName) AS x 
     JOIN 
     (SELECT l.DatabaseName, 
       SUM(l.T) AS 'Log', 
       SUM(l.U) AS 'Log_Used', 
       SUM(l.F) AS 'Log_Free' 
      FROM dbo.##Tbl_CombinedInfo l WHERE l.type = 'Log' GROUP BY l.DatabaseName) AS y 
     ON x.DatabaseName = y.DatabaseName; 

    IF @Unit = 'KB' 
     UPDATE @Tbl_Final SET TOTAL = TOTAL * 1024, 
     used = used * 1024, 
     free = free * 1024, 
     Data = Data * 1024, 
     Data_Used = Data_Used * 1024, 
     Data_Free = Data_Free * 1024, 
     Log = Log * 1024, 
     Log_Used = Log_Used * 1024, 
     Log_Free = Log_Free * 1024; 

    IF @Unit = 'GB' 
     UPDATE @Tbl_Final SET TOTAL = TOTAL/1024, 
     used = used/1024, 
     free = free/1024, 
     Data = Data/1024, 
     Data_Used = Data_Used/1024, 
     Data_Free = Data_Free/1024, 
     Log = Log/1024, 
     Log_Used = Log_Used/1024, 
     Log_Free = Log_Free/1024; 

     DECLARE @GrantTotal dec(11, 2); 
     SELECT @GrantTotal = SUM(TOTAL) FROM @Tbl_Final; 

     SELECT 
     CONVERT(dec(10, 2), TOTAL*100.0/@GrantTotal) AS 'WEIGHT (%)', 
     DatabaseName AS 'DATABASE', 
     CONVERT(VARCHAR(12), used) + ' (' + CONVERT(VARCHAR(12), [used (%)]) + ' %)' AS 'USED (%)', 
     [+], 
     CONVERT(VARCHAR(12), free) + ' (' + CONVERT(VARCHAR(12), [free (%)]) + ' %)' AS 'FREE (%)', 
     [=], 
     TOTAL, 
     [=], 
     CONVERT(VARCHAR(12), Data) + ' (' + CONVERT(VARCHAR(12), Data_Used) + ', ' + 
     CONVERT(VARCHAR(12), [Data_Used (%)]) + '%)' AS 'DATA (used, %)', 
     [+], 
     CONVERT(VARCHAR(12), Log) + ' (' + CONVERT(VARCHAR(12), Log_Used) + ', ' + 
     CONVERT(VARCHAR(12), [Log_Used (%)]) + '%)' AS 'LOG (used, %)' 
     FROM @Tbl_Final 
     WHERE DatabaseName LIKE ISNULL(@TargetDatabase, '%') 
     ORDER BY DatabaseName ASC; 

    IF @TargetDatabase IS NULL 
     SELECT CASE WHEN @Unit = 'GB' THEN 'GB' WHEN @Unit = 'KB' THEN 'KB' ELSE 'MB' END AS 'SUM', 
     SUM (used) AS 'USED', 
     SUM (free) AS 'FREE', 
     SUM (TOTAL) AS 'TOTAL', 
     SUM (Data) AS 'DATA', 
     SUM (Log) AS 'LOG' 
     FROM @Tbl_Final; 
    END 

RETURN (0) 

GO 
0

Sé que esto puede sonar un poco arcanine, pero ¿por qué no simplemente stat el directorio que contiene la base de datos.

0

si utiliza SQL Server Management Studio (de SQL 2005 o posterior), puede simplemente haga clic en Propiedades en la propia base de datos, y luego haga clic en la pestaña de almacenamiento.

Cuestiones relacionadas