#sql-server
#sql-сервер
Вопрос:
Я пытаюсь получить все имена таблиц и значения, присутствующие в определенном столбце, если столбец присутствует в базе данных. Для таблиц без столбца игнорируйте их.
Например: найдите все имена таблиц и значения из столбца ‘last_refresh_date’ в базе данных для всех таблиц со столбцом last_refresh_date.
Код, который я пробовал, это:
EXEC sp_MSforeachtable 'SELECT distinct ''?'' TableName, last_refresh_date FROM ?'
Я получаю сообщение об ошибке, поскольку в некоторых таблицах отсутствует имя столбца ‘last_refresh_date’.
Заранее спасибо за помощь
Комментарии:
1. Я полагаю, мой первый вопрос: почему вы хотите это сделать?
2. Я также уверен , что за последние несколько дней я ответил на вопрос, очень похожий на этот, но я не могу его найти.
3. Я пытаюсь создать таблицу, содержащую все имена таблиц в базе данных вместе с последней датой, на которую таблица была обновлена в соответствии со столбцом last_refresh_date, присутствующим в большинстве таблиц в БД. last_refresh_date имеет значение только для каждой таблицы
Ответ №1:
Я предполагаю, что вы используете последнюю версию SQL Server и, следовательно, имеете доступ к STRING_AGG
, если нет, вам нужно будет использовать «старый» FOR XML PATH
метод.
В любом случае, вы достигаете этого с помощью небольшого количества динамического SQL, и UNION ALL
. Я предполагаю, что вам также нужны имена таблиц и схем:
DECLARE @SQL nvarchar(MAX),
@ColumnName sysname = N'YourColumnName',
@CRLF nchar(2) = CHAR(13) CHAR(10);
DECLARE @Delimiter nvarchar(30) = @CRLF N'UNION ALL' @CRLF
SET @SQL = (SELECT STRING_AGG(N'SELECT N' QUOTENAME(s.[name],'''') N' AS SchemaName, N' QUOTENAME(t.[name],'''') N' AS TableName, ' QUOTENAME(c.[name]) N' FROM ' QUOTENAME(s.[name]) N'.' QUOTENAME(t.[name]), @Delimiter) WITHIN GROUP (ORDER BY t.object_id)
FROM sys.schemas s
JOIN sys.tables t ON s.schema_id = t.schema_id
JOIN sys.columns c ON t.object_id = c.object_id
WHERE c.[name] = @ColumnName)
EXEC sys.sp_executesql @SQL;