Как использовать sp_msforeachtable и sp_msforeachdb в одном запросе?

Есть ли способ ссылаться на таблицу внутри цикла sp_MSforeachtable внутри цикла sp_msforeachdb?

Например, в следующем запросе '?' всегда ссылается на базу данных:

DECLARE @cmd VARCHAR(8000);

SET @cmd = 'USE ?; EXEC sp_MSforeachtable @command1="select db_name = DB_NAME(), db_forearch = ''?'', tb_foreach = ''?'' "'

EXEC sp_msforeachdb @command1 =@cmd

В результате чего:

 db_name        db_forearch    tb_foreach
 ServerMonitor  master         master

Я хочу иметь что-то вроде:

 db_name        db_forearch    tb_foreach
 ServerMonitor  master         <TABLE_NAME>

Что я должен изменить?


Решаемые. Я использовал свой курсор, как предложил Шон. Но решение @replacechar, предложенное Беном Тулом, именно то, что я искал.

DECLARE @cmd VARCHAR(8000);

SET @cmd = 'USE ^; EXEC sp_MSforeachtable @command1="select db_name = DB_NAME(), db_forearch = ''^'', tb_foreach = ''?'' "'

EXEC sp_msforeachdb @command1 =@cmd, @replacechar = '^'

2 ответа

Решение

Посмотрите на параметры для sp_msforeachtable. Одним из них является @replacechar, который по умолчанию представляет собой знак вопроса (т.е.?). Не стесняйтесь передавать еще один столь же маловероятный символ в запросе (возможно, ^).

Конечно, было бы упущением, если бы я не упомянул, что в зависимости от того, что вы пытаетесь сделать (и я бы сказал, что все, что вы пытаетесь сделать для всех таблиц, выполнимо таким образом), есть читать (и писать) решения в powershell:

import-module sqlps -disablenamechecking;
$s = new-object microsoft.sqlserver.management.smo.server '.';
foreach ($db in $s.databases) {
   foreach ($table in $db.Tables) {
      $table | select parent, name; --merely list the table and database
   }
}

Для того, что вы делаете, вы можете сделать что-то вроде этого. Хотя это все еще использует для каждой процедуры БД, что может быть проблематично. Вы захотите добавить предложение where к последнему оператору select, чтобы отфильтровать некоторые базы данных (модель, tempdb, master и т. Д.)

declare @TableNames table
(
    DatabaseName sysname
    , TableName sysname
)
    insert @TableNames
    EXEC sp_msforeachdb @command1 = 'use ?;select ''?'', name from sys.tables'

select *, 'exec ' + Databasename + '..sp_spaceused [''' + TableName + ']'';' 
from @TableNames
Другие вопросы по тегам