如果我有一组这样的名字:
('first', 'fname', 'firstname', 'namef', 'namefirst', 'name')
SQL Server 2000 - 2008中检索特定数据库的上述集合中包含列名的不同表名的最佳方法是什么?
我想从显示的表列表中排除系统表和临时表。
SELECT so.name
FROM sysobjects so
INNER JOIN syscolumns sc
ON so.id = sc.id
WHERE sc.name IN ('first', 'fname', 'firstname', 'namef', 'namefirst', 'name')
我相信这是question的衍生物。
THX
答案 0 :(得分:4)
对于较新版本的SQL Server的FWIW我更喜欢INFORMATION_SCHEMA
上的目录视图,原因如下:
The case against INFORMATION_SCHEMA
views
另请参阅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已有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)
,您将不得不使用游标,一堆变量或highly not-recommended sp_msforeachdb。
答案 1 :(得分:3)
您可以使用INFORMATION_SCHEMA
架构。
SELECT DISTINCT t.TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES t
JOIN INFORMATION_SCHEMA.COLUMNS c
ON t.TABLE_NAME = c.TABLE_NAME
WHERE c.COLUMN_NAME IN (your list of names)
我不记得这是否包含临时表,但您可以查看TABLES
中的其他列以查看要过滤的内容。