Gor*_*ell 4 sql-server t-sql dbcc-checkdb
我创建了以下查询来列出服务器上所有数据库的 DBCC CHECKDB LastKnownGood 时间戳。有一个更好的方法吗?
IF OBJECT_ID(N'tempdb..#Results') IS NOT NULL
BEGIN
DROP TABLE #Results
END
CREATE TABLE #Results (ParentObject varchar(100), Object varchar(100), Field varchar(100), Value varchar(100))
GO
INSERT INTO #Results
EXEC sp_msForEachdb @command1 = 'DBCC DBINFO (''?'') WITH TABLERESULTS'
ALTER TABLE #Results ADD ID INT IDENTITY(1, 1)
GO -- required here
SELECT r.Value as [Database], r2.Value as CheckDB_LastKnownGood
FROM #Results r
INNER JOIN #Results r2
ON r2.ID = (SELECT MIN(ID) FROM #Results WHERE Field = 'dbi_dbccLastKnownGood' AND ID > r.ID)
WHERE r.Field = 'dbi_dbname'
ORDER BY r.Value
Run Code Online (Sandbox Code Playgroud)
我将使用 dbatools 模块 Get-DbaLastGoodCheckDb 中的 PowerShell 命令,这将使您能够一次性检查所有服务器。
这是命令的示例输出
您可以获得这样的详细信息
并像这样检查一大堆服务器
它也真的很快。在我的 10 个服务器和 125 个数据库的实验室中,它在 5.3 秒内完成
您可以在https://dbatools.io 上阅读有关 dbatools 的更多信息
sp_msForEachdb
您可以使用游标来代替Aaron 描述的有问题的 。
IF OBJECT_ID(N'tempdb..#Results') IS NOT NULL
BEGIN
DROP TABLE #Results;
END
CREATE TABLE #Results
(
DatabaseName SYSNAME NULL
, IsOnline BIT NULL
, ParentObject varchar(100) NULL
, [Object] varchar(100) NULL
, [Field] varchar(100) NULL
, [Value] varchar(100) NULL
);
DECLARE @cmd NVARCHAR(MAX);
DECLARE @dbName SYSNAME;
DECLARE @IsOnline BIT;
DECLARE cur CURSOR LOCAL FORWARD_ONLY STATIC
FOR
SELECT DBCCCommand = 'DBCC DBINFO(''' + d.name + ''') WITH TABLERESULTS;'
, DatabaseName = d.name
, IsOnline = CONVERT(BIT,
CASE WHEN d.state_desc = 'ONLINE' THEN 1 ELSE 0 END
)
FROM sys.databases d
ORDER BY d.name;
OPEN cur;
FETCH NEXT FROM cur INTO @cmd, @dbName, @IsOnline;
WHILE @@FETCH_STATUS = 0
BEGIN
RAISERROR (@dbName, 0, 1) WITH NOWAIT;
IF @IsOnline = 1
BEGIN
INSERT INTO #Results (ParentObject, [Object], [Field], [Value])
EXEC sp_executesql @cmd;
UPDATE #Results
SET DatabaseName = @dbName
, IsOnline = @IsOnline
WHERE DatabaseName IS NULL;
END
ELSE
BEGIN
INSERT INTO #Results (DatabaseName, IsOnline)
VALUES (@dbName, @IsOnline)
END
FETCH NEXT FROM cur INTO @cmd, @dbName, @IsOnline;
END
CLOSE cur;
DEALLOCATE cur;
SELECT r.DatabaseName
, LastKnownGoodDate = CONVERT(DATETIME, r.value, 120)
, r.IsOnline
FROM #Results r
WHERE r.field = 'dbi_dbccLastKnownGood'
OR r.field IS NULL;
Run Code Online (Sandbox Code Playgroud)
此输出具有数据库名称以及来自 DBCC DBINFO 输出的 LastKnownGood 列作为DATETIME
变量。不“在线”的数据库包含在输出中,LastKnownGoodDBCC
列设置为NULL
.
在我上面的例子中创建的游标是一个非常高效的本地、只进、静态游标。Local 表示游标的范围仅限于我们的会话,这显然不是问题(sp_msForEachdb 使用了一个设置起来非常昂贵的全局游标)。只进选项表示我们不打算通过游标向后滚动,并允许 SQL Server 使用只进、只读游标语义。静态选项强制 SQL Server 将游标结果具体化到 tempdb 中的临时表中,并从那里读取每一行。DECLARE CURSOR上的 MSDN 页面有关于游标选项的精彩细节,非常值得阅读和理解。
归档时间: |
|
查看次数: |
764 次 |
最近记录: |