5

有没有办法引用在“sp_msforeachdb”循环内运行的“sp_MSforeachtable”循环内的表?

例如,在以下查询中,“?” 总是引用数据库:

DECLARE @cmd VARCHAR(8000);

SET @cmd = 'USE ?; EXEC sp_MSforeachtable @command1="select db_name = DB_NAME(), db_foreach = ''?'', 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>

我应该改变什么?


解决了。按照 Sean 的建议,我使用了我的 ow 光标。但是 Ben Thul 建议的 @replacechar 解决方案正是我想要的。

DECLARE @cmd VARCHAR(8000);

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

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

2 回答 2

3

查看 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
   }
}
于 2014-12-02T16:56:18.847 回答
0

对于你正在做的事情,你可以做这样的事情。尽管这仍然使用 for each db 过程,这可能会出现问题。您将需要在最终的 select 语句中添加 where 子句以过滤掉一些数据库(模型、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
于 2014-12-02T16:26:48.217 回答