如何在同一个查询中同时使用sp_msforeachtable和sp_msforeachdb?

时间:2014-12-02 14:36:42

标签: sql-server sql-server-2008 sp-msforeachdb sp-msforeachtable

有没有办法在' 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>

我应该改变什么?


解决。我按照肖恩的建议使用了我的光标。但Ben Thul提出的@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 个答案:

答案 0 :(得分: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
   }
}

答案 1 :(得分:0)

对于你正在做的事情你可以做这样的事情。虽然这仍然使用每个db过程可能会有问题。您将需要在最终的select语句中添加where子句以过滤掉一些数据库(model,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