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?
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.
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
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 .
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
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:
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/
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
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.
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
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
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
).
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
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%')