关于如何从每个表中检索每一列及其数据类型,我已经看到了多个问题,以及许多其他信息,这些信息可以用此查询以最短的方式进行总结:
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
但是,是否有可能从列中获取所有数据,并且它们所属的行在表的第一行旁边呢?到目前为止,我还没有找到一种方法。是否可以这样做,也可能具有WHERE
条件,例如在返回表之前检查表是否包含特定列的列表,例如:
SELECT <AllTablesAndColumns+FirstRow>
FROM <WhereTheyCanBeSelectedFrom>
WHERE <TheTableHasTheseSpecificColumns>
将为每行返回表名,列名以及这些列中包含的数据。
答案 0 :(得分:0)
您可以构建动态查询:
DECLARE @sql NVARCHAR(MAX) =
N'SELECT *
FROM (VALUES (1)) AS s(n)
<joins>';
DECLARE @joins NVARCHAR(MAX)= '';
SELECT @joins += FORMATMESSAGE('LEFT JOIN (SELECT TOP 1 * FROM %s ) AS sub%s
ON 1=1' + CHAR(10), table_schema + '.' + table_name,
CAST(ROW_NUMBER() OVER(ORDER BY 1/0) AS VARCHAR(10)))
FROM (SELECT DISTINCT table_schema, table_name
FROM INFORMATION_SCHEMA.COLUMNS
-- WHERE ... -- custom logic based on column type/name/...
) s;
SET @sql = REPLACE(@sql, '<joins>', @joins);
PRINT @sql;
EXEC(@sql);
动态查询具有以下结构:
SELECT *
FROM (VALUES (1)) AS s(n) -- always 1 row
LEFT JOIN (SELECT TOP 1 * FROM dbo.tab1 ) AS sub1 ON 1=1 -- get single row
LEFT JOIN (SELECT TOP 1 * FROM dbo.tab2 ) AS sub2 ON 1=1
LEFT JOIN (SELECT TOP 1 * FROM dbo.tabC ) AS sub3 ON 1=1
请以它为起点。您可以使用WHERE
条件为每个子查询轻松扩展它,并返回特定的列而不是*。
编辑:
带有UNION ALL
的版本:
DECLARE @sql NVARCHAR(MAX);
SELECT @sql = COALESCE(@sql + ' UNION ALL', '') +
FORMATMESSAGE(' SELECT TOP 1 tab_name=''%s'',col_name=''%s'',col_val=%s FROM %s'+CHAR(10)
,table_name, column_name, column_name, table_schema + '.' + table_name)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE column_name LIKE 'colV%';
PRINT @sql;
EXEC(@sql);
答案 1 :(得分:0)
如果您正在寻找更多的EAV结构
假设我们正在查找列名称为 ZIPCODE
的所有表示例
Declare @S varchar(max) = ''
SELECT @S = @S +'+(Select top 1 SourceTable='''+A.Table_Name+''',* from '+quotename(A.Table_Name)+' for XML RAW)'
FROM INFORMATION_SCHEMA.COLUMNS A
Where COLUMN_NAME in ('ZipCode')
Declare @SQL varchar(max) = '
Declare @XML xml = '+stuff(@S,1,1,'')+'
Select SourceTable = r.value(''@SourceTable'',''varchar(100)'')
,Item = attr.value(''local-name(.)'',''varchar(100)'')
,Value = attr.value(''.'',''varchar(max)'')
From @XML.nodes(''/row'') as A(r)
Cross Apply A.r.nodes(''./@*'') AS B(attr)
Where attr.value(''local-name(.)'',''varchar(100)'') not in (''SourceTable'')
'
Exec(@SQL)
返回