Dla SQL Server 2005 i nowszych
FWIW dla nowszych wersji SQL Server Preferuję widoki katalogu niż INFORMATION_SCHEMA
z powodów opisanych w tym poście na blogu:
Sprawa przeciwko INFORMATION_SCHEMA
widoki
Zobacz także ostrzeżenia takie jak to na temat TABELA (Transact-SQL) na MSDN:
Zapytanie, którego użyłbym, byłoby następujące (filtrowanie obiektów systemowych, a także unikanie tabel #temp w przypadku, gdy jesteś w 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 '#%';
Aby powtórzyć to dla wszystkich baz danych:
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;
(COLLATE
klauzule są tam, aby zapobiec błędom w przypadku, gdy masz bazy danych z różnymi sortowaniami.)
Dla SQL Server 2000
Zauważ, że powyższe nie pomaga w przypadku SQL Server 2000, ale nie sądzę, abyś mógł stawiać sobie za cel możliwość uruchomienia tego samego zapytania w każdej wersji. SQL Server 2000 ma 13 lat i kilka lat bez wsparcia; z pewnością możesz uzasadnić posiadanie specjalnego kodu. W takim przypadku nadal wybrałbym zapytanie, które masz zamiast INFORMATION_SCHEMA
, po prostu odfiltruj obiekty systemowe i tabele tymczasowe (ponownie, istotne tylko w przypadku, gdy jesteś w 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;
Możesz to zrobić również dla każdej bazy danych w SQL Server 2000, ale ponieważ nie możesz użyć NVARCHAR(MAX)
będziesz musiał użyć kursora, kilku zmiennych lub wysoce niezalecane sp_msforeachdb
.