Ну, во-первых, прекратить использование sp_MSforEachDb
. О, проблемы (если вы хотите доказательства, см. here, here и here).
Как насчет:
DECLARE @cmd NVARCHAR(MAX) = N'', @sql NVARCHAR(MAX) = N'';
SELECT @cmd += N'IF EXISTS (SELECT 1 FROM '
+ QUOTENAME(name) + '.sys.tables WHERE name = N''Tabs'')
SET @sql += N''UNION ALL
SELECT ''''' + name + ''''',T.TabName
FROM ' + QUOTENAME(name) + '.dbo.Tabs AS T
WHERE EXISTS
(
SELECT 1 FROM ' + QUOTENAME(name) + '.dbo.TabModules AS TM
WHERE TM.TabID = T.TabID
AND TM.mID IN -- this should probably be exists too
(
...
)
)
'''
FROM sys.databases
WHERE state = 0 -- assume you only want online databases
AND database_id > 4; -- assume you don't want system dbs
EXEC sp_executesql @cmd, N'@sql NVARCHAR(MAX) OUTPUT', @sql OUTPUT;
SET @sql = STUFF(@sql, 1, 10, '') + N' ORDER BY TabName;';
PRINT @sql; -- this will appear truncated, but trust me, it is not truncated
-- EXEC sp_executesql @sql;
Если вы действительно хотите, чтобы некоторые неизвестные, произвольное число отдельных ResultSets, изменение просто.
DECLARE @cmd NVARCHAR(MAX) = N'', @sql NVARCHAR(MAX) = N'';
SELECT @cmd += N'IF EXISTS (SELECT 1 FROM '
+ QUOTENAME(name) + '.sys.tables WHERE name = N''Tabs'')
SET @sql += N''SELECT ''''' + name + ''''',T.TabName
FROM ' + QUOTENAME(name) + '.dbo.Tabs AS T
WHERE EXISTS
(
SELECT 1 FROM ' + QUOTENAME(name) + '.dbo.TabModules AS TM
WHERE TM.TabID = T.TabID
AND TM.mID IN -- this should probably be exists too
(
...
)
)
ORDER BY T.TabName;
'';'
FROM sys.databases
WHERE state = 0 -- assume you only want online databases
--AND database_id > 4; -- assume you don't want system dbs
EXEC sp_executesql @cmd, N'@sql NVARCHAR(MAX) OUTPUT', @sql OUTPUT;
PRINT @sql; -- this will appear truncated, but trust me, it is not truncated
-- EXEC sp_executesql @sql;
Спасибо за ответ Аарон! Я попробовал ваше решение, но вместо получения фактического результата я получил SQL-запрос, который был усечен в конце (извините, я полный noob, когда речь идет о функциях и sp). И когда я выполнил этот запрос отдельно (и добавил усеченную часть), результат был все в одной таблице (по сравнению с макетом результата из sp_MSforeachdb: одна таблица результатов для каждого БД). В любом случае, чтобы изменить это представление результата? – mustang888
SQL-запрос будет усечен в конце, если ваш запрос довольно большой и/или у вас есть большое количество баз данных. Я могу заверить, что на самом деле он не усекается, если у него действительно есть более миллиарда символов; это просто печальное ограничение в команде «PRINT». Я намеренно создал его как запрос UNION, потому что я не думаю, что это очень распространенное требование иметь неизвестное количество результатов. Если это то, что вы действительно хотите, вы всегда можете вывести вывод в таблицу #temp, а затем запустить курсор против этого, обрабатывая строки для каждого отдельного имени базы данных ... –
hmmm, это странно, потому что он определенно пропускает последние 30 символов или поэтому из запроса, и все же запрос waaaay под миллиардом символов (только 3 базы данных удовлетворяют условиям запроса). Кроме того, как я могу заставить эту команду выполнить запрос напрямую (без выполнения вручную сгенерированного запроса)? – mustang888