[英]Get data from every column in every table in a database | SQL Server
我已经看到了关于如何从每个表中检索每个列及其数据类型的多个问题,以及许多其他信息,这些信息可以使用此查询以最短的方式进行总结:
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
但是,是否有可能从它们所属的列和行中获取所有数据, 从而获得表中的第一行呢? 到目前为止,我还没有找到一种方法。 是否可以这样做,也可能具有WHERE
条件,例如在返回表之前检查表是否包含特定列的列表,例如:
SELECT <AllTablesAndColumns+FirstRow>
FROM <WhereTheyCanBeSelectedFrom>
WHERE <TheTableHasTheseSpecificColumns>
这将返回表名,列名以及每一行的这些列中包含的数据。
您可以构建动态查询:
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);
如果您正在寻找更多的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)
返回
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.