3

有没有什么办法可以在'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 [email protected] 

结果造成:

db_name  db_forearch tb_foreach 
ServerMonitor master   master 

我想有这样的:

db_name  db_forearch tb_foreach 
ServerMonitor master   <TABLE_NAME> 

我应该怎么改?


已解决。按照肖恩的建议,我使用了我的ow游标。但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 [email protected], @replacechar = '^' 
+0

你只是试图从每个数据库中获取每个表名? – 2014-12-02 14:40:58

+0

没有。我的目标有点复杂(我想为sp_spaceused为数据库中的每个表运行脚本)。这个例子只是为了更容易理解。 – Michael 2014-12-02 15:47:16

+0

为什么不直接推出自己的游标而不是每个数据库?无论如何,这个程序有一些问题。它并不总是找到每个数据库。 http://sqlblog.com/blogs/aaron_bertrand/archive/2010/12/29/a-more-reliable-and-more-flexible-sp-msforeachdb.aspx – 2014-12-02 15:56:11

回答

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 
    } 
} 
0

对于你在做什么,你可以做这样的事情。虽然这仍然使用每个数据库程序可能有问题。您将要where子句加入到最终的select语句来过滤掉一些数据库(模型,tempdb中,硕士等)

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 
相关问题