Here is a T-SQL script used for inventory purpose on your SQL Server Databases.
Tested in: SQL Server 2016/SQL Server 2017
Script:
drop table if exists #SQLDatabaseInventory;
create table #SQLDatabaseInventory(
ServerName varchar(128) default @@servername
, database_id bigint
, DBName varchar(128) default db_name()
, DBOwner varchar(128)
, CreateDate datetime2
, RecoveryModel varchar(12)
, StateDesc varchar(60)
, CompatibilityLevel int
, DataFileSizeMB int
, LogFileSizeMB int
, DataUsageMB int
, IndexUsageMB int
, SizeMB decimal(17,2)
, Collation varchar(60)
, UserCount int
, RoleCount int
, TableCount int
, SPCount int
, UDFCount int
, ViewCount int
, DMLTriggerCount int
, IsCaseSensitive bit
, IsTrustWorthy bit
, LastFullBackupDate datetime2
, LastDiffBackupDate datetime2
, LastLogBackupDate datetime2
, IsTracked sql_variant);
insert into #SQLDatabaseInventory(database_id,DBName, DBOwner, CreateDate, RecoveryModel, StateDesc, CompatibilityLevel, IsCaseSensitive
, IsTrustWorthy, Collation, LastFullBackupDate, LastDiffBackupDate, LastLogBackupDate, IsTracked)
select database_id,name, suser_sname(owner_sid), create_date, recovery_model_desc, state_desc,compatibility_level
, IsCaseSensitive=CAST(CHARINDEX(N'_CS_', collation_name) AS bit), is_trustworthy_on, Collation_Name
, t.LastFullBackup, t.LastDiffBackup, t.LastLogBackup
, Case when is_cdc_enabled = 1 Then 'CDC' else '' End
from master.sys.databases db
outer apply( SELECT
MAX(CASE WHEN b.type = 'D' THEN b.backup_finish_date END) AS LastFullBackup,
MAX(CASE WHEN b.type = 'I' THEN b.backup_finish_date END) AS LastDiffBackup,
MAX(CASE WHEN b.type = 'L' THEN b.backup_finish_date END) AS LastLogBackup
FROM msdb.dbo.backupset b
where b.database_name = db.name
) t;
EXEC master.dbo.sp_msforeachdb'use [?]
update t set SizeMB=(select sum(size)/128. from dbo.sysfiles)
, DataUsageMB=x.DataUsageMB, IndexUsageMB=x.IndexUsageMB
, DataFileSizeMB = u.DBSize, LogFileSizeMB = u.LogSize
, TableCount=y.TC, UDFCount=y.UC, SPCount = y.SC, ViewCount=y.VC
, DMLTriggerCount=y.DC
, UserCount = z.UC, RoleCount = z.RC
from #SQLDatabaseInventory t
outer apply (
SELECT SUM(case when df.type in (0,2,4) then df.size else 0 end)/128
, SUM(case when df.type in (1,3) then df.size else 0 end)/128
FROM sys.database_files df
) u(DBSize, LogSize)
outer apply(select DataUsageMB=sum(
CASE
When it.internal_type IN (202,204,207,211,212,213,214,215,216,221,222,236) Then 0
When a.type <> 1 and p.index_id < 2 Then a.used_pages
When p.index_id < 2 Then a.data_pages
Else 0
END)/128,
IndexUsageMB=(sum(a.used_pages)-sum(
CASE
When it.internal_type IN (202,204,207,211,212,213,214,215,216,221,222,236) Then 0
When a.type < > 1 and p.index_id < 2 Then a.used_pages
When p.index_id < 2 Then a.data_pages
Else 0
END
))/128
from sys.partitions p join sys.allocation_units a on p.partition_id = a.container_id
left join sys.internal_tables it on p.object_id = it.object_id
) x
outer apply
( select SC=Sum(case Type when ''P'' then 1 else 0 end)
, DC=Sum(case Type when ''TR'' then 1 else 0 end)
, TC=Sum(case Type when ''U'' then 1 end)
, UC= sum(case when Type in (''TF'', ''IF'', ''FN'') then 1 else 0 end)
, VC=Sum(case Type when ''V'' then 1 else 0 end)
from sys.objects where object_id > 1024
and type in (''U'',''P'',''TR'',''V'',''TF'',''IF'',''FN'')
) y
outer apply
( select UC = sum(case when [Type] in (''G'',''S'',''U'') then 1 else 0 end)
, RC = sum(case when Type = ''R'' then 1 else 0 end)
from sys.database_principals
where principal_id > 4
) z where t.DBName=db_name();
'
SELECT A.*,
Case when is_parameterization_forced = 1 then 'ON' ELSE 'OFF' END is_parameterization_forced,
Case when is_query_store_on = 1 Then 'ON' ELSE 'OFF' End is_query_store_on,
Case When is_broker_enabled = 1 Then 'ON' ELSE 'OFF' End is_broker_enabled,log_reuse_wait_desc,
Case when is_read_only = 1 Then 'READ-ONLY' Else 'ALL' End is_read_only,
Case When is_auto_close_on = 1 Then 'Enabled' Else 'Disabled' End is_auto_close_on,
Case When is_auto_shrink_on = 1 Then 'Enabled' Else 'Disabled' End is_auto_shrink_on,
Case When is_auto_update_stats_on = 1 Then 'Enabled' Else 'Disabed' End is_auto_update_stats_on
FROM #SQLDatabaseInventory A
inner join sys.databases B
On B.database_id = A.database_id
I would really love to hear from you what else you would like to see to this list?
See Also:
https://sqlzealots.com/2020/04/26/sql-server-inventory-queries-sql-server-instances/
I’d like to grow my readership. If you enjoyed this blog post, please share it with your friends!
i am having more then 2000 server list, which is having all list of server details like instname, appown,appdivision, deatabase type at one place means one server. looking to prepare database inventory, can you suggest the better way to create database inventory
LikeLike