我正在处理一个查询,该查询收集了一些与数据库还原有关的信息,但是在获取正确的数据库大小时遇到了麻烦。以下查询为我提供了数据库名称,上次还原日期,数据库大小以及最后一次还原数据库的用户的用户名。
WITH lastrestores AS
(
SELECT
DatabaseName = [d].[name],
[r].[restore_date],
[f].[size],
[r].[user_name],
RowNum = ROW_NUMBER() OVER (PARTITION BY d.NAME ORDER BY r.[restore_date] DESC)
FROM
master.sys.databases d
LEFT OUTER JOIN
msdb.dbo.[restorehistory] r ON r.[destination_database_name] = d.NAME
LEFT JOIN
master.sys.master_files f ON d.database_id = f.database_id
)
SELECT *
FROM [lastrestores]
WHERE [rownum] = 1
AND databasename LIKE 'stuff%'
ORDER BY restore_date DESC
但是,这没有显示正确的数据库大小。当我检查.mdf
文件和数据库属性中的大小时,它显示的大小小于此查询返回的大小。当我检查sp_databases
存储过程时,它表明数据库大小已完成:
DATABASE_SIZE = CONVERT(INT,
CASE -- more than 2TB(maxint) worth of pages (by 8K each) can not fit an int...
WHEN SUM(CONVERT(BIGINT, s_mf.size)) >= 268435456
THEN NULL
ELSE SUM(CONVERT(BIGINT, s_mf.size)) * 8 -- Convert from 8192 byte pages to Kb
END)
我尝试将此部分合并到原始查询中,但是遇到“未包含在聚合函数或分组依据中”错误:
WITH lastrestores AS
(
SELECT
DatabaseName = [d].[name],
[r].[restore_date],
CONVERT(INT,
CASE
WHEN SUM(CONVERT(BIGINT, [f].[size])) >= 268435456
THEN NULL
ELSE SUM(CONVERT(BIGINT, [f].[size])) * 8
END) AS DBSize,
[r].[user_name],
RowNum = ROW_NUMBER() OVER (PARTITION BY d.NAME ORDER BY r.[restore_date] DESC)
FROM
master.sys.databases d
LEFT OUTER JOIN
msdb.dbo.[restorehistory] r ON r.[destination_database_name] = d.NAME
LEFT JOIN
master.sys.master_files f ON d.database_id = f.database_id
)
SELECT *
FROM [lastrestores]
WHERE [rownum] = 1
AND databasename LIKE 'stuff%'
ORDER BY restore_date DESC
虽然我确实了解此错误的基本知识,但我不确定如何调整此错误,因此我可以得到所需的信息,因为此查询比以往更加复杂。我的理想结果是我发布的原始查询,但具有正确的数据库大小,如sp_databases
中所示。我该如何实现?
答案 0 :(得分:2)
如果您只是想转换大小列以匹配属性中的值,则只需将页面转换为MB-因此乘以8即可得到KB,然后除以1024即可得到MB。
WITH lastrestores AS
(
SELECT
DatabaseName = [d].[name],
[r].[restore_date],
[size] = CAST([f].[size] * 8 / 1024.0 AS DECIMAL(10,2)) ,
[r].[user_name],
RowNum = ROW_NUMBER() OVER (PARTITION BY d.NAME ORDER BY r.[restore_date] DESC)
FROM
master.sys.databases d
LEFT OUTER JOIN
msdb.dbo.[restorehistory] r ON r.[destination_database_name] = d.NAME
LEFT JOIN
master.sys.master_files f ON d.database_id = f.database_id
)
SELECT *
FROM [lastrestores]
WHERE [rownum] = 1
ORDER BY restore_date DESC
由于SSMS向上取整,因此此Size值可能比在属性中看到的值更准确。
我担心的是,如果您有多个数据文件,这将无法准确显示数据库的非日志大小。
我可能会做类似的事情来包含所有数据文件。
SELECT
DatabaseName = DB_NAME(f.database_id)
,r.restore_date
,CAST(SUM(f.size * 8 / 1024.0) AS DECIMAL(10,2))
,r.user_name
FROM sys.master_files f
OUTER APPLY
(SELECT TOP 1 * FROM msdb.dbo.[restorehistory] r WHERE r.[destination_database_name] = DB_NAME(f.database_id) ORDER BY restore_date desc) r
WHERE f.type = 0
GROUP BY f.database_id, r.restore_date, r.user_name
ORDER BY r.restore_date desc