艰难!| 数据库教程18:SQL Server获取DBCC中某一项或收集DBCC的结果到表中

493 阅读4分钟

这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战

以表格形式显示DBCC的结果

DBCC命令的执行,大多数结果是表格形式。比如dbcc useroptions;

有的却是文本格式的结果,比如DBCC CHECKDB

DBCC CHECKDB用于检查数据库中有没有损坏发生。同时尽力修复数据库的损坏,使数据库能够被重新正常访问。

DBCC CHECKDB;DBCC CHECKDB();检查的是当前数据库。

DBCC CHECKDB WITH NO_INFOMSGS;禁止信息性消息,这样可以仅获取错误或异常消息。

输出结果为文本格式的DBCC命令,大多数都可以通过with TABLERESULTS参数实现以表格形式显示DBCC的结果。

DBCC CHECKDB([AdventureWorks2016]) with TABLERESULTS;

获取DBCC结果中的某一项数据或收集DBCC的结果到表中

收集DBCC的结果到表中,更多的还是获得表格形式的结果。尤其是在编程开发中,需要获取到DBCC的结果数据,可以先将其插入一个表或临时表中,然后SLECT查询该表,即可获取到结果,及结果中的某一项数据项。

通过INSERT INTO <table> EXECUTE ('DBCC xxx');,可以将DBCC命令作为动态SQL字符串放在EXEC/EXECUTE中执行,并将其结果插入到一个表或临时表中,这样就可以依据条件查询某一项数据了。

示例1:执行DBCC CHECKDB命令并将结果插入到一个表或临时表中

如下,创建一个临时表(或表)。

DECLARE @Database_Name NVARCHAR(50)
SET @Database_Name = 'master';

CREATE TABLE #DBCC
(
  [Error] VARCHAR(255) ,
  [Level] VARCHAR(255) ,
  [State] VARCHAR(255) ,
  [MessageText] VARCHAR(255) ,
  [RepairLevel] VARCHAR(255) ,
  [Status] VARCHAR(255) ,
  [DBId] VARCHAR(255) ,
  [DBFragId] VARCHAR(255) ,
  [ObjectId] VARCHAR(255) ,
  [IndexId] VARCHAR(255) ,
  [PartitionId] VARCHAR(255) ,
  [AllocUnitId] VARCHAR(255) ,
  [RIdDBId] VARCHAR(255) ,
  [RIdPruId] VARCHAR(255) ,
  [File] VARCHAR(255) ,
  [Page] VARCHAR(255) ,
  [Slot] VARCHAR(255) ,
  [RefDBId] VARCHAR(255) ,
  [RefPruId] VARCHAR(255) ,
  [RefFile] VARCHAR(255) ,
  [RefPage] VARCHAR(255) ,
  [RefSlot] VARCHAR(255) ,
  [Allocation] VARCHAR(255)
);

INSERT INTO #DBCC
             ( Error ,
               [Level] ,
               [State] ,
               MessageText ,
               RepairLevel ,
               [Status] ,
               [DBId] ,
               DBFragId ,
               ObjectId ,
               IndexId ,
               PartitionId ,
               AllocUnitId ,
               RIdDBId ,
               RIdPruId ,
               [File] ,
               [Page] ,
               Slot ,
               RefDBId ,
               RefPruId ,
               RefFile ,
               RefPage ,
               RefSlot ,
               Allocation )
EXEC ('DBCC CHECKDB ([' + @Database_Name + ']) WITH ALL_ERRORMSGS, TABLERESULTS, NO_INFOMSGS;' );
SELECT * FROM #DBCC;

-- 可以根据需要添加`NO_INFOMSGS`,禁止信息性消息。

示例2:执行DBCC CHECKCONSTRAINTS命令并将其结果插入到一个表中

create table DBCC_Check_Constratints
(
Table_Name varchar(128),
Constraint_Name varchar(128),
Where_Location varchar(255)
);
-- DBCC CHECKCONSTRAINTS('[dbo].[AWBuildVersion]') WITH ALL_CONSTRAINTS;
INSERT INTO DBCC_Check_Constratints EXEC('DBCC CHECKCONSTRAINTS([AWBuildVersion]);');
select * from DBCC_Check_Constratints;
drop table DBCC_Check_Constratints;

DBCC CHECKCONSTRAINTS( table_name | table_id | constraint_name | constraint_id ) 检查当前数据库中指定表上的指定约束或所有约束的完整性。即验证表的约束。

由于DBCC CHECKCONSTRAINTS返回的是违反约束的约束名,所以通常如果没有问题,返回的是空结果集。

DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;检查当前数据库中所有表上的所有启用和禁用约束的完整性。

示例3:使用表变量接收DBCC USEROPTIONS的执行结果

Declare @T table (Options varchar(100),Value varchar(100));
Insert Into @T 
Exec('DBCC USEROPTIONS');

-- 获取当前用户的时间格式
Select * 
 From @T 
 Where Options ='dateformat';

-- 获取当前连接的隔离级别
Select * 
 From @T 
 Where Options ='isolation level';

示例4:使用系统视图或表替代执行DBCC SHOWFILESTATS命令获取信息

DBCC SHOWFILESTATS命令可以查看数据库文件的信息,比如总空间大小、已使用空间等。而对于想要获取相同的信息,或者需要使用SELECT返回数据到应用程序。则可以使用替代方案,比如使用sys.database_files数据库视图也可以获取相同的信息。

DBCC SHOWFILESTATS;

执行'dbcc showfilestats'动态SQL获取数据到一个表变量中,然后再计算数据库的数据文件剩余空间占比:

declare @FileStats table
(
  Fileid int,
  [FileGroup] int,
  TotalExtents int,
  UsedExtents int,
  Name varchar(255),
  [FileName] varchar(max)
)
insert into @FileStats execute('dbcc showfilestats');

select  1-convert(float, sum(UsedExtents))/convert(float, sum(TotalExtents)) as FreeDataSpace from @FileStats;

替代方案直接使用sys.database_files数据库视图,计算数据库的数据文件(mdf)剩余空间占比:

-- size 为 8-KB pages的大小
SELECT sum(db_f.size)/128.0 FileSizeInMB,CAST(sum(FILEPROPERTY(db_f.name, 'SpaceUsed')) AS int)/128.0 
   AS SpaceUsedInMB, convert(float, (sum(db_f.size) - sum(fileproperty(db_f.name,'SpaceUsed')))) / sum(db_f.size) NotUsedPercent
FROM sys.database_files db_f
WHERE db_f.type = 0;

此部分参考自How to retrieve results from 'DBCC SHOWFILESTATS' with ODBC?