2

次のSQLサーバークエリを使用して、名前に文字列「コード」が含まれる列を含むテーブルのスキーマ内のすべてのテーブルと列の名前をリストするために、次のSQLを使用しています。

SELECT 
    a.table_name, a.column_name from (SELECT t.name AS table_name,
    SCHEMA_NAME(schema_id) AS schema_name,
    c.name AS column_name
FROM 
    sys.tables AS t
INNER JOIN 
    sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE 
    c.name LIKE '%code%') a

結果:

Table Name     Column Name
----------     -----------
Tab_1_name     a_code
Tab_2_name     another_code
Tab_3_name     yet_another_code
and so on...

ラッパーを使用して a_code 列と another_code 列の実際のデータをクエリしたいのですが、実際のデータを取得する方法がわかりません (たとえば、タブ 1 を個別に行う場合は、

SELECT a_code FROM Tab_1

取得するため

a_code
------
value 1
value 2
value 3

しかし、次の行に沿って何かを取得できるように、外側のクエリをコーディングして上記をラップする方法を見つけたり見つけたりすることはできません。

Tab1_name  a_code
---------  ------
tab_name 1 value 1
tab_name 1 value 2
tab_name 2 value 1
tab_name 2 value 2
tab_name 3 value 1
tab_name 3 value 2 ... etc.

つまり、名前に「コード」という単語が含まれているスキーマ/DB のすべてのテーブル列のすべてのデータ値のフォーマットされたリストですか?

4

2 に答える 2

2

動的 SQL がなければ、とにかくこれを行うことはできません。

ここから始めましょう。

DECLARE @SearchTerm NVARCHAR(50)

SELECT @SearchTerm = '%id%'

SELECT  t.name AS table_name,
        SCHEMA_NAME(schema_id) AS schema_name,
        c.name AS column_name
INTO #temp
FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE c.name LIKE @SearchTerm
ORDER BY t.name

DECLARE @Query      NVARCHAR(MAX),
        @tableName  NVARCHAR(250),
        @schemaName NVARCHAR(10),
        @columnName NVARCHAR(250)


SELECT @Query = 'SELECT SchemaName = '''',
                        TableName = '''',
                        ColumnName = '''',
                        Value = CONVERT(NVARCHAR(MAX), '''')
                 WHERE 0 = 1'

WHILE(EXISTS(SELECT TOP 1 1 FROM #temp))
BEGIN

    SELECT TOP 1    @tableName = table_name,
                    @schemaName = [schema_name],
                    @columnName = column_name
    FROM #temp

    SELECT @Query = @Query + ' UNION ALL SELECT SchemaName = ''' + @schemaName + ''',
                                                TableName = ''' + @tableName + ''',
                                                ColumnName = ''' + @columnName + ''',
                                                Value = CASE WHEN ' + @columnName + ' IS  NULL THEN ''NULL'' ELSE CONVERT(NVARCHAR(MAX), ' + @columnName + ') END
                                         FROM ' + @tableName

    DELETE #temp
    WHERE table_name = @tableName
    AND @schemaName = [schema_name]
    AND @columnName = column_name

END

PRINT @Query

EXEC  sp_executesql @Query

DROP TABLE #temp

上記のクエリは次の情報を返します: SchemaName TableName ColumnName Value

一致するすべての列の値を返すと、変換の問題や null 変換の問題が発生する可能性が非常に高いことに注意してください。上記のクエリでは、基本的なケースが処理されますが、'NVARCHAR' への変換は、一部の複雑な SQL 列の型で失敗する場合があります。

于 2016-03-11T17:37:00.047 に答える
0
use master
GO
declare
  @sql varchar(max) = '',
  @colpattern varchar(100) = '%name%'

;with cteSchema as
(
  select
    object_schema_name(t.object_id) + '.' + quotename(t.name) as tabname,
    quotename(c.name) as colname
  from sys.tables t
  inner join sys.columns c on c.object_id = t.object_id
  where c.name like @colpattern
)
select @sql = 
  (
    select
        cast('
        select cast(t.' as varchar(max)) + t.colname + ' as varchar(1000)) as [value] '
        + ', cast(''' + t.tabname + '.' + t.colname + ''' as nvarchar(2000)) as [source] '
        + ' from ' + t.tabname + ' t
        union all '
    from cteSchema t
    order by t.tabname, t.colname
    for xml path(''), type
  ).value('.', 'varchar(max)') 
  + ' 
  select null, null where 1=0
  order by [source], [value]'

print @sql

exec (@sql)
GO
于 2016-03-11T19:33:13.423 に答える