如果我有一组这样的名字:
('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 的派生词我相信。
谢谢
最佳答案
适用于 SQL Server 2005 及以上
FWIW 对于较新版本的 SQL Server 我更喜欢目录 View 而不是 INFORMATION_SCHEMA
,原因在这篇博文中概述:
The case against INFORMATION_SCHEMA
views
另请参阅关于主题 TABLES (Transact-SQL) 的类似警告在 MSDN 上:
Do not use INFORMATION_SCHEMA views to determine the schema of an object. The only reliable way to find the schema of an object is to query the sys.objects catalog view. INFORMATION_SCHEMA views could be incomplete since they are not updated for all new features.
因此我将使用的查询如下(过滤掉系统对象并避免在您使用 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)
,您将不得不使用游标、一组变量,或者highly not-recommended sp_msforeachdb .
关于sql-server - 如何从 SQL Server 2000-2008 中的多个表中选择名称集中的列名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14525279/