För SQL Server 2005 och senare
FWIW för nyare versioner av SQL Server Jag föredrar katalogvyerna framför INFORMATION_SCHEMA
av de skäl som beskrivs i det här blogginlägget:
Rättegången mot INFORMATION_SCHEMA
visningar
Se även varningar som denna om ämnet TABELLER (Transact-SQL) på MSDN:
Så frågan jag skulle använda skulle vara följande (filtrera bort systemobjekt och även undvika #temp-tabeller om du är i 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 '#%';
För att upprepa detta för alla databaser:
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
satser är till för att förhindra fel i de fall du har databaser med olika sorteringar.)
För SQL Server 2000
Observera att ovanstående inte hjälper för SQL Server 2000, men jag tycker inte att du ska göra det till ett mål att kunna köra samma fråga på varje enskild version. SQL Server 2000 är 13 år gammal och flera år utan support; visst kan du motivera att ha speciell kod för det. I så fall skulle jag fortfarande välja den fråga du har över INFORMATION_SCHEMA
, filtrera bara bort systemobjekt och temporära tabeller (återigen, endast relevant om du är i 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;
Du kan göra detta för varje databas i SQL Server 2000 också, men eftersom du inte kan använda NVARCHAR(MAX)
du måste antingen använda en markör, ett gäng variabler eller rekommenderas starkt inte sp_msforeachdb
.