获取所有数据库中表的行数
Get number of rows for tables across all databases
搜索了一下,没有看到任何真正符合我需求的东西(尽管我并不真正理解 SQL 除了基本的 select 语句,所以也许我只是错过了它)。许多个月前在学校上了 SQL class。
我有:
- 虚拟 Windows 服务器 2008 R2 运行 SQL 2008 R2。我通过 MS SQL Server Management Studio
连接
- 90-100 个数据库
- 所有数据库都具有相同的 table 结构(每个都是不同的客户端)
我想:
- 搜索所有数据库和return所有数据库的列表,其中 table (TableName) 大于 5000 条记录。
- 我可以安排的某种脚本将使用该列表,如果它找到一个 TableName table 超过 5000 条记录的数据库,将删除超过 x 天的所有内容(比如 30 ).任何类型的记录以了解过去几天发生的事情都是一种奖励。
如有任何帮助,我们将不胜感激。谢谢。
EDIT/UPDATE (2/24/15):Hiren Dhaduk 提供了一个很好用的存储过程。谢谢!
您可以在任何数据库中使用以下存储过程。然后 运行 这个存储过程通过传递 table 名称和 NoOfRows(table 的最小行数,在你的情况下它将是 5000):
CREATE PROCEDURE usp_FindLargeTables
@TableName VARCHAR(256) , @NoOfRows int
AS
BEGIN
DECLARE @DBName VARCHAR(256)
DECLARE @varSQL VARCHAR(512)
DECLARE @getDBName CURSOR
SET @getDBName = CURSOR FOR
SELECT name
FROM sys.databases
WHERE state != 6
CREATE TABLE #TmpTable (TableName VARCHAR(256),
SchemaName VARCHAR(256),
DBName VARCHAR(256))
OPEN @getDBName
FETCH NEXT
FROM @getDBName INTO @DBName
WHILE @@FETCH_STATUS = 0
BEGIN
SET @varSQL = 'USE ' + @DBName + ';
INSERT INTO #TmpTable
SELECT
sysobjects.Name as TableName
, sysindexes.Rows as NoOfRows , '''+ @DBName + ''' AS DBName
FROM
sysobjects
INNER JOIN sysindexes
ON sysobjects.id = sysindexes.id
WHERE
type = ''U''
AND sysindexes.IndId < 2
and sysobjects.Name = '''+ @TableName +''' and sysindexes.Rows > ' + CONVERT(VARCHAR, @NoOfRows) + ''
EXEC (@varSQL)
FETCH NEXT
FROM @getDBName INTO @DBName
END
CLOSE @getDBName
DEALLOCATE @getDBName
SELECT *
FROM #TmpTable
WHERE DBName != 'master'
-- STEP 2
DECLARE @DYNAMICQUERY VARCHAR(MAX)
SET @DYNAMICQUERY =
REPLACE((
SELECT 'DELETE FROM ['+ DBName +'].[dbo].['+ TableName +'] where Createdate < DATEADD(day, -30, GETDATE());'
FROM #TmpTable
WHERE DBName != 'master'
FOR XML PATH('')
), '<' , '<');
EXEC(@DYNAMICQUERY);
DROP TABLE #TmpTable
END
Example : usp_FindLargeTables 'DeltaStuds',5000
关于第二点的澄清:
Unless you run a trace when the changes happen it is not possible.
因此,为此我建议您在此 table 中放置一个名为 createdate 的列,然后您将能够删除 30 天前创建的记录。
你问的是你的设置的自定义...
您可以使用以下查询来识别具有 row count greater than 5000
的表
SELECT sc.name +'.'+ ta.name TableName
FROM sys.tables ta
INNER JOIN sys.partitions pa
ON pa.OBJECT_ID = ta.OBJECT_ID
INNER JOIN sys.schemas sc
ON ta.schema_id = sc.schema_id
WHERE ta.is_ms_shipped = 0 AND pa.index_id IN (1,0)
and ta.name = 'DeltaStuds'
GROUP BY sc.name,ta.name
having SUM(pa.rows)>5000
但是对于所有数据库,您都需要 link 到 运行 这样的东西。 How to find column names for all tables in all databases in SQL Server。我不知道有更简单的方法...
对于第二部分,您必须设置一个删除过程,该过程从上述查询中获取结果集,创建一个动态查询并根据您的日期字段删除行。在该过程中,您可以注入一个审计机制来记录删除操作、行数、日期时间等...
搜索了一下,没有看到任何真正符合我需求的东西(尽管我并不真正理解 SQL 除了基本的 select 语句,所以也许我只是错过了它)。许多个月前在学校上了 SQL class。
我有:
- 虚拟 Windows 服务器 2008 R2 运行 SQL 2008 R2。我通过 MS SQL Server Management Studio 连接
- 90-100 个数据库
- 所有数据库都具有相同的 table 结构(每个都是不同的客户端)
我想:
- 搜索所有数据库和return所有数据库的列表,其中 table (TableName) 大于 5000 条记录。
- 我可以安排的某种脚本将使用该列表,如果它找到一个 TableName table 超过 5000 条记录的数据库,将删除超过 x 天的所有内容(比如 30 ).任何类型的记录以了解过去几天发生的事情都是一种奖励。
如有任何帮助,我们将不胜感激。谢谢。
EDIT/UPDATE (2/24/15):Hiren Dhaduk 提供了一个很好用的存储过程。谢谢!
您可以在任何数据库中使用以下存储过程。然后 运行 这个存储过程通过传递 table 名称和 NoOfRows(table 的最小行数,在你的情况下它将是 5000):
CREATE PROCEDURE usp_FindLargeTables
@TableName VARCHAR(256) , @NoOfRows int
AS
BEGIN
DECLARE @DBName VARCHAR(256)
DECLARE @varSQL VARCHAR(512)
DECLARE @getDBName CURSOR
SET @getDBName = CURSOR FOR
SELECT name
FROM sys.databases
WHERE state != 6
CREATE TABLE #TmpTable (TableName VARCHAR(256),
SchemaName VARCHAR(256),
DBName VARCHAR(256))
OPEN @getDBName
FETCH NEXT
FROM @getDBName INTO @DBName
WHILE @@FETCH_STATUS = 0
BEGIN
SET @varSQL = 'USE ' + @DBName + ';
INSERT INTO #TmpTable
SELECT
sysobjects.Name as TableName
, sysindexes.Rows as NoOfRows , '''+ @DBName + ''' AS DBName
FROM
sysobjects
INNER JOIN sysindexes
ON sysobjects.id = sysindexes.id
WHERE
type = ''U''
AND sysindexes.IndId < 2
and sysobjects.Name = '''+ @TableName +''' and sysindexes.Rows > ' + CONVERT(VARCHAR, @NoOfRows) + ''
EXEC (@varSQL)
FETCH NEXT
FROM @getDBName INTO @DBName
END
CLOSE @getDBName
DEALLOCATE @getDBName
SELECT *
FROM #TmpTable
WHERE DBName != 'master'
-- STEP 2
DECLARE @DYNAMICQUERY VARCHAR(MAX)
SET @DYNAMICQUERY =
REPLACE((
SELECT 'DELETE FROM ['+ DBName +'].[dbo].['+ TableName +'] where Createdate < DATEADD(day, -30, GETDATE());'
FROM #TmpTable
WHERE DBName != 'master'
FOR XML PATH('')
), '<' , '<');
EXEC(@DYNAMICQUERY);
DROP TABLE #TmpTable
END
Example : usp_FindLargeTables 'DeltaStuds',5000
关于第二点的澄清:
Unless you run a trace when the changes happen it is not possible.
因此,为此我建议您在此 table 中放置一个名为 createdate 的列,然后您将能够删除 30 天前创建的记录。
你问的是你的设置的自定义...
您可以使用以下查询来识别具有 row count greater than 5000
SELECT sc.name +'.'+ ta.name TableName
FROM sys.tables ta
INNER JOIN sys.partitions pa
ON pa.OBJECT_ID = ta.OBJECT_ID
INNER JOIN sys.schemas sc
ON ta.schema_id = sc.schema_id
WHERE ta.is_ms_shipped = 0 AND pa.index_id IN (1,0)
and ta.name = 'DeltaStuds'
GROUP BY sc.name,ta.name
having SUM(pa.rows)>5000
但是对于所有数据库,您都需要 link 到 运行 这样的东西。 How to find column names for all tables in all databases in SQL Server。我不知道有更简单的方法...
对于第二部分,您必须设置一个删除过程,该过程从上述查询中获取结果集,创建一个动态查询并根据您的日期字段删除行。在该过程中,您可以注入一个审计机制来记录删除操作、行数、日期时间等...