1

このような名前のセットがある場合:

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

これは、私が信じているこの質問の派生物です。

どうも

4

2 に答える 2

4

SQLServer2005以降の場合

INFORMATION_SCHEMASQL Serverの新しいバージョンのFWIWこのブログ投稿で概説されている理由から、カタログビューよりもカタログビューの方が好きです。

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句は、異なる照合のデータベースがある場合のエラーを防ぐためにあります。)

SQLServer2000の場合

上記はSQLServer2000には役立ちませんが、すべてのバージョンで同じクエリを実行できるようにすることを目標にするべきではないと思います。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を使用する必要があります。

于 2013-01-25T16:28:10.063 に答える
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を見て、何をフィルター処理するかを確認できます。

于 2013-01-25T15:56:17.063 に答える