对于 SQL Server 2005 及更高版本
对于较新版本的 SQL Server 的 FWIW 我更喜欢目录视图INFORMATION_SCHEMA
,原因在此博客文章中概述:
反对INFORMATION_SCHEMA
意见的案例
另请参阅MSDN上关于TABLES (Transact-SQL)主题的警告:
不要使用 INFORMATION_SCHEMA 视图来确定对象的架构。查找对象架构的唯一可靠方法是查询 sys.objects 目录视图。INFORMATION_SCHEMA 视图可能不完整,因为它们并未针对所有新功能进行更新。
因此,我将使用的查询如下(过滤掉系统对象并在您使用 tempdb 时避免使用 #temp 表):
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 '#%';
对所有数据库重复此操作:
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
子句是为了防止在您拥有具有不同排序规则的数据库的情况下出现错误。)
对于 SQL Server 2000
请注意,上述内容对 SQL Server 2000 没有帮助,但我认为您不应该将能够在每个版本上运行相同的查询作为目标。SQL Server 2000 已有 13 年的历史,几年后不再支持;当然,您可以证明有特殊代码是合理的。在这种情况下,我仍然会选择您所拥有的查询INFORMATION_SCHEMA
,只需过滤掉系统对象和临时表(同样,仅与您在 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;
您也可以对 SQL Server 2000 中的每个数据库执行此操作,但由于您不能使用NVARCHAR(MAX)
,您将不得不使用游标、一堆变量或高度不推荐的 sp_msforeachdb。