sql-server - 如何从 SQL Server 2000-2008 中的多个表中选择名称集中的列名称

标签 sql-server sql-server-2008 sql-server-2005 sql-server-2000

如果我有一组这样的名字:

('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/

相关文章:

c# - XML 文件到 SQL 附加插入

sql-server-2005 - JPA/Hibernate/MS SQL Server 不返回生成的 id 值

mysql - SSIS将英文BlobColumn转换为以汉字结尾的字符串

mysql - 分组依据和列选择

sql - #tem_table 的对象名称无效

mysql - 单个 sql 中有多个 count* sql

sql-server-2008 - SQL Server 2008 R2 中的统计过程控制图

sql - 使用多个类似条件选择查询

sql - 如何通过 sql server 2008 中的 XP_CMDSHELL 通过网络访问文件/文件夹?

sql-server - SQL Server sp_msforeachtable 用法仅选择满足某些条件的表