web-dev-qa-db-fra.com

Comment extraire le nombre de lignes pour toutes les tables d'une base de données SQL SERVER

Je recherche un script SQL pouvant être utilisé pour déterminer s’il existe des données (nombre de lignes) dans l’une des tables d’une base de données donnée.

L'idée est de ré-incarner la base de données au cas où il y aurait des lignes existantes (dans l'une des bases de données).

La base de données dont on parle est Microsoft SQL SERVER.

Quelqu'un pourrait-il suggérer un exemple de script?

234
vijaysylvester

Le code SQL suivant vous donnera le nombre de lignes de toutes les tables d'une base de données:

CREATE TABLE #counts
(
    table_name varchar(255),
    row_count int
)

EXEC sp_MSForEachTable @command1='INSERT #counts (table_name, row_count) SELECT ''?'', COUNT(*) FROM ?'
SELECT table_name, row_count FROM #counts ORDER BY table_name, row_count DESC
DROP TABLE #counts

Le résultat sera une liste de tables et leur nombre de lignes.

Si vous souhaitez simplement connaître le nombre total de lignes sur l'ensemble de la base de données, ajoutez:

SELECT SUM(row_count) AS total_row_count FROM #counts

vous obtiendrez une valeur unique pour le nombre total de lignes dans la base de données entière.

373
adrianbanks

Si vous voulez passer le temps et les ressources nécessaires, il faut compter (*) vos tables de 3 millions de lignes. Essayez ceci avec SQL SERVER Central de Kendal Van Dyke.


Nombre de lignes à l'aide de sysindexes Si vous utilisez SQL 2000, vous devez utiliser sysindexes de la manière suivante:

-- Shows all user tables and row counts for the current database 
-- Remove OBJECTPROPERTY function call to include system objects 
SELECT o.NAME,
  i.rowcnt 
FROM sysindexes AS i
  INNER JOIN sysobjects AS o ON i.id = o.id 
WHERE i.indid < 2  AND OBJECTPROPERTY(o.id, 'IsMSShipped') = 0
ORDER BY o.NAME

Si vous utilisez SQL 2005 ou 2008, l'interrogation de sysindexes fonctionnera toujours, mais Microsoft vous conseille de supprimer ces sysindexes dans une version ultérieure de SQL Server. Il est donc recommandé d'utiliser plutôt les DMV, comme suit:

-- Shows all user tables and row counts for the current database 
-- Remove is_ms_shipped = 0 check to include system objects 
-- i.index_id < 2 indicates clustered index (1) or hash table (0) 
SELECT o.name,
  ddps.row_count 
FROM sys.indexes AS i
  INNER JOIN sys.objects AS o ON i.OBJECT_ID = o.OBJECT_ID
  INNER JOIN sys.dm_db_partition_stats AS ddps ON i.OBJECT_ID = ddps.OBJECT_ID
  AND i.index_id = ddps.index_id 
WHERE i.index_id < 2  AND o.is_ms_shipped = 0 ORDER BY o.NAME 
185
Keng

Fonctionne sur Azure, ne nécessite pas de procs stockés.

SELECT t.name, s.row_count from sys.tables t
JOIN sys.dm_db_partition_stats s
ON t.object_id = s.object_id
AND t.type_desc = 'USER_TABLE'
AND t.name not like '%dss%'
AND s.index_id IN (0,1)

Crédit .

92

Celui-ci a l'air mieux que les autres, je pense.

USE  [enter your db name here]
GO

SELECT      SCHEMA_NAME(A.schema_id) + '.' +
        --A.Name, SUM(B.rows) AS 'RowCount'  Use AVG instead of SUM
          A.Name, AVG(B.rows) AS 'RowCount'
FROM        sys.objects A
INNER JOIN sys.partitions B ON A.object_id = B.object_id
WHERE       A.type = 'U'
GROUP BY    A.schema_id, A.Name
GO
43
İsmet Alkan

Court et doux

sp_MSForEachTable 'DECLARE @t AS VARCHAR(MAX); 
SELECT @t = CAST(COUNT(1) as VARCHAR(MAX)) 
+ CHAR(9) + CHAR(9) + ''?'' FROM ? ; PRINT @t'

Sortie:

enter image description here

20
Rikin Patel

SQL Server 2005 ou une version ultérieure donne un rapport plutôt intéressant sur la taille des tableaux, notamment le nombre de lignes, etc.

Par programme, il existe une solution Nice à l’adresse suivante: http://www.sqlservercentral.com/articles/T-SQL/67624/

14
Peter Schofield
SELECT 
    sc.name +'.'+ ta.name TableName, SUM(pa.rows) RowCnt
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)
GROUP BY sc.name,ta.name
ORDER BY SUM(pa.rows) DESC
13
Rikin Patel

N'utilisez pas SELECT COUNT(*) FROM TABLENAME, car il s'agit d'une opération gourmande en ressources. Il faut utiliser Vues de gestion dynamique SQL Server ou Catalogues système pour obtenir les informations sur le nombre de lignes de toutes les tables d'une base de données.

9
Ashish Kumar Mehta

Je voudrais apporter un changement mineur à la solution de Frederik. J'utiliserais la procédure stockée système sp_spaceused, qui inclura également les tailles de données et d'index.


declare c_tables cursor fast_forward for 
select table_name from information_schema.tables 

open c_tables 
declare @tablename varchar(255) 
declare @stmt nvarchar(2000) 
declare @rowcount int 
fetch next from c_tables into @tablename 

while @@fetch_status = 0 
begin 

    select @stmt = 'sp_spaceused ' + @tablename 

    exec sp_executesql @stmt

    fetch next from c_tables into @tablename 

end 

close c_tables 
deallocate c_tables 
3
Vod

sélectionnez toutes les lignes de la vue information_schema.tables et émettez une instruction count (*) pour chaque entrée renvoyée à partir de cette vue.

declare c_tables cursor fast_forward for
select table_name from information_schema.tables

open c_tables
declare @tablename varchar(255)
declare @stmt nvarchar(2000)
declare @rowcount int
fetch next from c_tables into @tablename

while @@fetch_status = 0
begin

    select @stmt = 'select @rowcount = count(*) from ' + @tablename

    exec sp_executesql @stmt, N'@rowcount int output', @rowcount=@rowcount OUTPUT

    print N'table: ' + @tablename + ' has ' + convert(nvarchar(1000),@rowcount) + ' rows'

    fetch next from c_tables into @tablename

end

close c_tables
deallocate c_tables
2
Frederik Gheysels

Voici une approche SQL dynamique qui vous donne également le schéma:

DECLARE @sql nvarchar(MAX)

SELECT
    @sql = COALESCE(@sql + ' UNION ALL ', '') +
        'SELECT
            ''' + s.name + ''' AS ''Schema'',
            ''' + t.name + ''' AS ''Table'',
            COUNT(*) AS Count
            FROM ' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name)
    FROM sys.schemas s
    INNER JOIN sys.tables t ON t.schema_id = s.schema_id
    ORDER BY
        s.name,
        t.name

EXEC(@sql)

Si nécessaire, il serait facile d’étendre cette opération à toutes les bases de données de l’instance (joindre à sys.databases).

2
Jon Seigel
    SELECT
          SUM(sdmvPTNS.row_count) AS [DBRows]
    FROM
          sys.objects AS sOBJ
          INNER JOIN sys.dm_db_partition_stats AS sdmvPTNS
                ON sOBJ.object_id = sdmvPTNS.object_id
    WHERE 
          sOBJ.type = 'U'
          AND sOBJ.is_ms_shipped = 0
          AND sdmvPTNS.index_id < 2
    GO
1
Howard Rothenburg

Ceci est ma solution préférée pour SQL 2008, qui place les résultats dans une table temporaire "TEST" que je peux utiliser pour trier et obtenir les résultats dont j'ai besoin:

SET NOCOUNT ON 
DBCC UPDATEUSAGE(0) 
DROP TABLE #t;
CREATE TABLE #t 
( 
[name] NVARCHAR(128),
[rows] CHAR(11),
reserved VARCHAR(18), 
data VARCHAR(18), 
index_size VARCHAR(18),
unused VARCHAR(18)
) ;
INSERT #t EXEC sp_msForEachTable 'EXEC sp_spaceused ''?''' 
SELECT * INTO TEST FROM #t;
DROP TABLE #t;
SELECT  name, [rows], reserved, data, index_size, unused FROM TEST \
WHERE ([rows] > 0) AND (name LIKE 'XXX%')
1
djangofan