Получить данные из каждого столбца в каждой таблице в базе данных | SQL Server - PullRequest
0 голосов
/ 09 сентября 2018

Я видел несколько вопросов о том, как извлечь каждый столбец из каждой таблицы вместе с ее типом данных, среди многих других частей информации, которые можно кратко суммировать с помощью этого запроса:

SELECT * 
FROM INFORMATION_SCHEMA.COLUMNS

Однако возможно ли получить все данные из столбцов, а строк, которым они принадлежат , получить первую строку в таблице вместе с этим? Я не нашел способ сделать это до сих пор. Можно ли сделать это, возможно, также иметь условие WHERE, например, проверять, содержит ли таблица список определенных столбцов, прежде чем возвращать его, например ::100100

SELECT <AllTablesAndColumns+FirstRow> 
FROM <WhereTheyCanBeSelectedFrom> 
WHERE <TheTableHasTheseSpecificColumns>

Что будет возвращать имя таблицы, имя столбца и данные, содержащиеся в этих столбцах для каждой строки.

Ответы [ 2 ]

0 голосов
/ 09 сентября 2018

Если вы ищете больше структуры 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)

Возвращает

enter image description here

0 голосов
/ 09 сентября 2018

Вы можете построить динамический запрос:

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);

Демоверсия DBFiddle

Динамический запрос имеет структуру:

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 для каждого подзапроса и вернуть конкретные столбцы вместо *.


EDIT:

Версия с 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);

DBFiddle Demo2

...