获取所有数据库中表的行数

时间:2015-01-29 20:23:15

标签: sql sql-server sql-server-2008

搜索了一下,没有看到任何真正符合我需求的东西(虽然我不太了解基本选择语句之外的SQL,所以也许我只是错过了它)。很多以前在学校里上过SQL课程。

我有:

  • 运行SQL 2008 R2的虚拟Windows Server 2008 R2。我通过MS SQL Server Management Studio连接
  • 90-100数据库
  • 所有数据库都具有相同的表结构(每个数据库都是不同的客户端)

我想:

  • 搜索所有数据库并返回所有数据库的列表,这些数据库的表(TableName)大于5000条记录。
  • 我可以安排的某种脚本将使用该列表,如果它找到一个DB,TableName表超过5000条记录,将删除超过x天数的任何数据(比如说30)。任何类型的记录都知道过去几天发生的事情将是一个奖励。

任何帮助将不胜感激。谢谢。

EDIT / UPDATE(2/24/15):Hiren Dhaduk提供了一个很好的存储过程。谢谢!

2 个答案:

答案 0 :(得分:0)

您可以在任何数据库中使用以下存储过程。然后通过传递表名和NoOfRows运行此存储过程(表的最小行数,在您的情况下将为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('')
), '&lt;' , '<');

EXEC(@DYNAMICQUERY);

DROP TABLE #TmpTable
END
  

示例:usp_FindLargeTables&#39; DeltaStuds&#39;,5000

澄清你的第二点:

  

除非您在更改发生时运行跟踪,否则无法进行跟踪。

为此,我建议您在此表中放置一个名为createdate的列,然后您就可以删除30天之前创建的记录。

答案 1 :(得分:0)

您所询问的内容非常适合您的设置......

您可以使用以下查询来识别包含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

但是你需要像这个链接来为所有数据库运行它。 How to find column names for all tables in all databases in SQL Server。我不知道更简单的方法......

对于第二部分,您必须设置一个删除过程,该过程从上面的查询中获取结果集,创建动态查询并根据您的日期字段删除行。在该过程中,您可以注入一个审计机制,记录删除操作,行计数,日期时间等...