列出所有用户数据库中的所有表

Hik*_*ari 2 sql-server sql-server-2012

sys.tables 列出单个数据库中的所有用户表,但没有它们的架构名称。

如果我在创建代码时知道现有数据库,我可以使用它USE来浏览所有数据库,查询sys.tables其表,并将列表插入到临时表中以供以后使用。

但是,有没有更简单的方法来做到这一点,并且通过唯一的查询能够从所有用户数据库中检索所有用户表及其架构?

Aar*_*and 7

我有一个稍微不同的方法:

  • 我倾向于警告不要sp_msforeachdb因为它没有记录,不受支持,并且有一个已知的错误,它可以默默地跳过数据库,并且 Microsoft 没有兴趣修复它(请参阅此处此处此处此处此处)。
  • 我喜欢构建一个动态的 SQL 语句,它可以在执行前进行检查,也可以先打印出来进行按摩,而不是简单地将其扔进黑匣子。我还想确保该语句仅尝试针对在线且用户可以访问的数据库运行。

    DECLARE @src NVARCHAR(MAX), @sql NVARCHAR(MAX);
    
    SELECT @sql = N'', @src = N' UNION ALL 
    SELECT ''$d'', 
        s.name COLLATE SQL_Latin1_General_CP1_CI_AI,
        t.name COLLATE SQL_Latin1_General_CP1_CI_AI
      FROM [$d].sys.schemas AS s
      INNER JOIN [$d].sys.tables AS t
      ON s.[schema_id] = t.[schema_id]';
    
    SELECT @sql = @sql + REPLACE(@src, '$d', name)
      FROM sys.databases
      WHERE database_id > 4
        AND [state] = 0
        AND HAS_DBACCESS(name) = 1;
    
    SET @sql = STUFF(@sql, 1, 10, CHAR(13) + CHAR(10));
    
    PRINT @sql;
    --EXEC sys.sp_executesql @sql;
    
    Run Code Online (Sandbox Code Playgroud)

注意:这将轰炸名称中带有单引号/撇号 ( ') 的数据库。这看起来很公平,因为谁做的?

如果您需要将结果放入临时表以备后用:

CREATE TABLE #t(d SYSNAME, s SYSNAME, t SYSNAME);
INSERT #t EXEC sys.sp_executesql @sql;
Run Code Online (Sandbox Code Playgroud)