Pour SQL Server 2005 et supérieur
FWIW pour les nouvelles versions de SQL Server, je préfère les vues de catalogue à INFORMATION_SCHEMA
pour les raisons décrites dans cet article de blog :
L'affaire contre INFORMATION_SCHEMA
vues
Consultez également les avertissements comme celui-ci sur le sujet TABLES (Transact-SQL) sur MSDN :
Donc, la requête que j'utiliserais serait la suivante (filtrant les objets système et évitant également les tables #temp dans le cas où vous seriez dans tempdb):
SELECT t.name, c.name
FROM sys.tables AS t
INNER JOIN sys.columns AS c
ON t.[object_id] = c.[object_id]
WHERE c.name IN (N'name', N'firstname', etc.)
AND t.is_ms_shipped = 0
AND t.name NOT LIKE '#%';
Pour répéter ceci pour toutes les bases de données :
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += N'
UNION ALL SELECT db = N''' + name + ''',
t.name COLLATE Latin1_General_CI_AI,
c.name COLLATE Latin1_General_CI_AI
FROM ' + QUOTENAME(name) + '.sys.tables AS t
INNER JOIN ' + QUOTENAME(name) + 'sys.columns AS c
ON t.[object_id] = c.[object_id]
WHERE c.name IN (N''name'', N''firstname'', etc.)
AND t.is_ms_shipped = 0
AND t.name NOT LIKE ''#%'''
FROM sys.databases
-- WHERE ... -- probably don't need system databases at least
SELECT @sql = STUFF(@sql, 1, 18, '')
-- you may have to adjust ^^ 18 based on copy/paste, cr/lf, tabs etc.
+ ' ORDER BY by db, s.name, o.name';
EXEC sp_executesql @sql;
(Le COLLATE
les clauses sont là pour éviter les erreurs dans le cas où vous avez des bases de données avec des classements différents.)
Pour SQL Server 2000
Notez que ce qui précède n'aide pas pour SQL Server 2000, mais je ne pense pas que vous devriez vous fixer comme objectif de pouvoir exécuter la même requête sur chaque version. SQL Server 2000 a 13 ans et n'est plus pris en charge depuis plusieurs années; vous pouvez sûrement justifier d'avoir un code spécial pour cela. Dans ce cas, je choisirais toujours la requête que vous avez sur INFORMATION_SCHEMA
, filtrez simplement les objets système et les tables temporaires (encore une fois, uniquement pertinent si vous êtes dans tempdb) :
SELECT [object] = so.name, [column] = sc.name,
[type] = st.name, [precision] = st.xprec,
[scale] = st.xscale, st.length
FROM sysobjects AS so
INNER JOIN syscolumns AS sc
ON so.id = sc.id
INNER JOIN systypes AS st
ON sc.xtype = st.xtype
WHERE sc.name IN
(N'first', N'fname', N'firstname', N'namef', N'namefirst', N'name')
AND so.name NOT LIKE '#%'
AND OBJECTPROPERTY(so.id, 'IsMsShipped') = 0;
Vous pouvez également le faire pour chaque base de données dans SQL Server 2000, mais comme vous ne pouvez pas utiliser NVARCHAR(MAX)
vous devrez soit utiliser un curseur, un tas de variables, soit le sp_msforeachdb fortement déconseillé
.