Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come selezionare i nomi delle colonne da più tabelle in SQL Server 2000-2008 che si trovano in un set di nomi

Per SQL Server 2005 e versioni successive

FWIW per le versioni più recenti di SQL Server preferisco le viste del catalogo su INFORMATION_SCHEMA per i motivi illustrati in questo post del blog:

Il caso contro INFORMATION_SCHEMA visualizzazioni

Vedi anche avvisi come questo sull'argomento TABELLE (Transact-SQL) su MSDN:

Quindi la query che userei sarebbe la seguente (filtrando gli oggetti di sistema ed evitando anche le tabelle #temp nel caso in cui ti trovi in ​​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 '#%';

Per ripetere questo per tutti i database:

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;

(Il COLLATE le clausole servono a prevenire errori nel caso in cui si disponga di database con regole di confronto diverse.)

Per SQL Server 2000

Si noti che quanto sopra non aiuta per SQL Server 2000, ma non credo che si dovrebbe avere come obiettivo essere in grado di eseguire la stessa query su ogni singola versione. SQL Server 2000 ha 13 anni e diversi anni non sono più supportati; sicuramente puoi giustificare avere un codice speciale per questo. In tal caso sceglierei comunque la query che hai su INFORMATION_SCHEMA , filtra semplicemente gli oggetti di sistema e le tabelle temporanee (di nuovo, rilevante solo nel caso in cui ti trovi in ​​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;

Puoi farlo anche per ogni database in SQL Server 2000, ma poiché non puoi usare NVARCHAR(MAX) dovrai usare un cursore, un gruppo di variabili o sp_msforeachdb altamente sconsigliato .