Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment sélectionner des noms de colonnes à partir de plusieurs tables dans SQL Server 2000-2008 qui se trouvent dans un ensemble de noms

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é .