326 votes

Comment récupérer le nombre de lignes pour toutes les tables d'une base de données SQL SERVER ?

Je suis à la recherche d'un script SQL qui peut être utilisé pour déterminer s'il y a des données (c'est-à-dire le 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 n'importe quelle base de données).

La base de données dont il est question est Microsoft SQL SERVER .

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

468voto

adrianbanks Points 36858

Le SQL suivant vous permettra d'obtenir 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

La sortie sera une liste de tableaux et leur nombre de lignes.

Si vous voulez simplement le nombre total de lignes dans toute la base de données, il suffit d'ajouter :

SELECT SUM(row_count) AS total_row_count FROM #counts

vous donnera une seule valeur pour le nombre total de lignes dans toute la base de données.

0 votes

Super, fonctionne comme décrit (bien que cela prenne un certain temps), c'est aussi une bonne chose car je ne suis pas autorisé à exécuter les rapports, merci.

7 votes

J'ai upvoted ceci - mais je pense qu'il est important de mentionner que sp_MSForEachTable est une procédure non documentée - afaik, cela signifie que MS ne la supporte pas et peut la supprimer des futures versions sans préavis ?

2 votes

@MarkD Oui, c'est exact, bien qu'il existe depuis plusieurs versions de SQL Server sans changement.

247voto

Keng Points 10618

Si vous voulez contourner le temps et les ressources nécessaires pour compter (*) vos tables de 3 millions de lignes. Essayez ceci par SQL SERVER Central par Kendal Van Dyke.


Comptage des lignes à l'aide de sysindex Si vous utilisez SQL 2000, vous devrez utiliser les sysindex comme suit :

-- 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 des sysindex fonctionnera toujours, mais Microsoft indique que les sysindex pourraient être supprimés dans une future version de SQL Server. Par conséquent, vous devriez utiliser les DMV à la place, 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

0 votes

Ok, le script fonctionne mais nécessite un "use DB" au début de celui-ci. Donc, bien que ça fonctionne tel quel, c'était trompeur.

4 votes

Sur ma base de données, la réponse acceptée prend 10 secondes. Ce site la réponse prend 0 ! +1 pour toi Keng. Bien que j'aie ajouté JOIN sys.schemas s ON s.schema_id = o.schema_id et inclus s.Name pour voir les noms de tables qualifiés.

6 votes

Notez que l'utilisation de sysindexes ou de dm_dp_partition_stats vous donnera une approximation du nombre de rangs !

161voto

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 .

2 votes

A quoi sert "AND t.name not like '%dss%'" ?

4 votes

@quillbreaker : exclusion des tables créées par SQL Azure Data Sync

1 votes

Ça a bien marché. Je me suis assis et j'ai dit "ça peut prendre du temps" et ça a été fait en deux secondes. J'avais affaire à une base de données de 528 tables et je n'avais aucune idée de sa taille réelle.

74voto

Ismet Alkan Points 2703

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

8 votes

+1 : cette requête nécessite juste data_reader permissions.

4 votes

Je ne sais pas pourquoi, mais cette requête ne compte pas les lignes dans toutes les tables avec précision. Les comptages dans certaines tables sont doublés. J'ai trouvé que la requête de Rikin Patel était exacte.

11 votes

@Dan La différence entre celle-ci et celle de Rikin Patel est que celle-ci ne vérifie pas que l'index_id de l'entrée sys.partitions est soit 0 soit 1. Donc ce n'est pas seulement que certaines lignes sont doublées, c'est que certaines lignes sont multipliées par le nombre d'index qu'elles ont. Ainsi, si vous avez une table contenant 100 lignes et que vous avez défini 3 index sur celle-ci, la requête ci-dessus affichera 3*100=300 lignes pour cette table.

17voto

Peter Schofield Points 624

Le serveur SQL 2005 ou plus récent fournit un rapport très intéressant indiquant la taille des tables, y compris le nombre de lignes, etc. Il se trouve dans les rapports standard et s'intitule Disc Usage by Table.

Du point de vue programmatique, il existe une solution intéressante : http://www.sqlservercentral.com/articles/T-SQL/67624/

5 votes

Sans aucun droit d'administration, cela fonctionne bien. SELECT T.name AS [TABLE NAME], I.rows AS [ROWCOUNT] FROM sys.tables AS T INNER JOIN sys.sysindexes AS I ON T.object_id = I.id AND I.indid < 2 ORDER BY I.rows DESC

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X