如何查询数据库中的空表

cod*_*mer 28 sql-server system-tables

由于一些“开发人员”,我们在我们的系统上工作,我们遇到了空表的问题。我们发现在传输到云端的过程中,有几个表被复制了,但其中的数据没有。

我想运行一个查询系统表来查找哪些用户表是空的。我们使用的是 MS SQL 2008 R2。

谢谢您的帮助。

Mik*_*Fal 46

杠杆sys.tablessys.partitions

select
    t.name table_name,
    s.name schema_name,
    sum(p.rows) total_rows
from
    sys.tables t
    join sys.schemas s on (t.schema_id = s.schema_id)
    join sys.partitions p on (t.object_id = p.object_id)
where p.index_id in (0,1)
group by t.name,s.name
having sum(p.rows) = 0;
Run Code Online (Sandbox Code Playgroud)

使用行总和只是为了确保您不会与分区表混淆。Index_ID 为 0 或 1 意味着您只查看堆或聚集索引的行数。


Han*_*non 9

正如 Mike Fal 和 Kin 都指出的那样,系统表是您的朋友。

对于代码更完整的版本,我提出了以下内容,它可以让您查看数据库中每个表使用的总数据空间。

USE master;

CREATE DATABASE TestDB;
GO

USE tempdb;
ALTER DATABASE TestDB SET RECOVERY SIMPLE;
GO

USE TestDB;
CREATE TABLE Test1 (
    Test1ID INT NOT NULL PRIMARY KEY IDENTITY(1,1)
    , TestData nvarchar(255) CONSTRAINT DF_Test1_TestData DEFAULT (NEWID())
);

GO

TRUNCATE TABLE Test1;

SELECT s.name + '.' + t.name AS TableName,
    sum(p.rows) AS TotalRows,
    SUM(au.data_pages) AS DataPagesUsed
FROM sys.tables t
    INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
    INNER JOIN sys.partitions p ON t.object_id = p.object_id
    INNER JOIN sys.allocation_units au ON p.hobt_id = au.container_id
WHERE au.type = 1 or au.type = 3 
    AND t.is_ms_shipped = 0
GROUP BY s.name, t.name
    ORDER BY SUM(au.data_pages) DESC;

INSERT INTO Test1 DEFAULT VALUES;

SELECT s.name + '.' + t.name AS TableName,
    sum(p.rows) AS TotalRows,
    SUM(au.data_pages) AS DataPagesUsed
FROM sys.tables t
    INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
    INNER JOIN sys.partitions p ON t.object_id = p.object_id
    INNER JOIN sys.allocation_units au ON p.hobt_id = au.container_id
WHERE au.type = 1 or au.type = 3 
    AND t.is_ms_shipped = 0
GROUP BY s.name, t.name
    ORDER BY SUM(au.data_pages) DESC;
Run Code Online (Sandbox Code Playgroud)

最后 3 条语句的结果:

在此处输入图片说明


小智 6

这是一个 PowerShell 版本:

使用 SQL Server 管理对象 (SMO)


function Find-EmptyTables ($server,$database) 
{

    # Load SMO assembly
    [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | Out-Null

    $s = New-Object 'Microsoft.SqlServer.Management.Smo.Server' $server
    $db = $s.Databases.Item($database)
    $db.Tables | Where-Object { $_.RowCount -eq 0 } | Select Schema, Name, RowCount
}
Run Code Online (Sandbox Code Playgroud)

根据数据库的数量,您可以对填充在变量中的每个数据库名称的列表使用上述函数,并在处理一台服务器的情况下同时输出它:


$DBList = 'MyDatabase1','MyDatabase2'

foreach ($d in $DBList) {
Find-EmptyTables -server MyServer -database $d | 
  Select @{Label="Database";Expression={$d}}, Schema, Name, RowCount
}
Run Code Online (Sandbox Code Playgroud)