Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como selecionar nomes de colunas de várias tabelas no SQL Server 2000-2008 que estão em um conjunto de nomes

Para SQL Server 2005 e superior


FWIW para versões mais recentes do SQL Server, prefiro as exibições de catálogo em INFORMATION_SCHEMA pelos motivos descritos neste post do blog:

O caso contra INFORMATION_SCHEMA visualizações

Consulte também avisos como este no tópico TABLES (Transact-SQL) no MSDN:

Portanto, a consulta que eu usaria seria a seguinte (filtrando objetos do sistema e também evitando tabelas #temp no caso de você estar no 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 '#%';

Para repetir isso para todos os bancos de dados:
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;

(O COLLATE cláusulas existem para evitar erros no caso de você ter bancos de dados com agrupamentos diferentes.)

Para SQL Server 2000


Observe que o acima não ajuda para o SQL Server 2000, mas não acho que você deva ter como meta poder executar a mesma consulta em todas as versões. O SQL Server 2000 tem 13 anos e vários anos sem suporte; certamente você pode justificar ter um código especial para isso. Nesse caso, eu ainda escolheria a consulta que você tem em INFORMATION_SCHEMA , apenas filtre os objetos do sistema e as tabelas temporárias (novamente, relevante apenas no caso de você estar no 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;

Você também pode fazer isso para cada banco de dados no SQL Server 2000, mas como não pode usar NVARCHAR(MAX) você terá que usar um cursor, um monte de variáveis ​​ou o sp_msforeachdb altamente não recomendado .