在所有数据库的所有对象中查找表名

时间:2011-09-01 01:46:09

标签: sql-server sql-server-2008

我有一个包含多个数据库和客户端应用程序的系统。所有数据库都在一个SQL Server实例上。它们是由不同的人在不同的时间开发的。因此,如果发生某些错误,很难找到哪个程序或触发数据被修改。

现在我使用这个脚本,我在这个网站上找到了:

SELECT  DISTINCT ISNULL(sd.referenced_schema_name+'.','')+ OBJECT_NAME(sd.referenced_id)TableName,
        OBJECT_NAME(sd.referencing_id)Ref_Object,
        CASE WHEN OBJECTPROPERTYEX(sd.referencing_id,N'IsUserTable')= 1
                     THEN'Table'
        WHEN OBJECTPROPERTYEX(sd.referencing_id,N'IsTableFunction')= 1
                     THEN'Function'
        WHEN OBJECTPROPERTYEX(sd.referencing_id,N'IsTableFunction')= 1
                     THEN'Function'
        WHEN OBJECTPROPERTYEX(sd.referencing_id,N'IsScalarFunction')=1
                     THEN'Function'
        WHEN OBJECTPROPERTYEX(sd.referencing_id,N'IsTrigger')= 1
                     THEN'Trigger'
        WHEN OBJECTPROPERTYEX(sd.referencing_id,N'IsView')= 1
                     THEN'View'
        WHEN OBJECTPROPERTYEX(sd.referencing_id,N'IsUserTable')= 1
                     THEN'Table'
        WHEN OBJECTPROPERTYEX(sd.referencing_id,N'IsProcedure')= 1
                     THEN'Procedure'
        WHEN OBJECTPROPERTYEX(sd.referencing_id,N'IsIndexed')= 1
                     THEN'Index'
        WHEN OBJECTPROPERTYEX(sd.referencing_id,N'IsForeignKey')= 1
                     THEN'ForeignKey'
        WHEN OBJECTPROPERTYEX(sd.referencing_id,N'IsPrimaryKey')= 1
                     THEN'PrimaryKey'
        END AS Ref_Object_Name
FROM    sys.sql_expression_dependencies SD
        INNER JOIN sys.objects obj
                     ON obj.object_id=sd.referenced_id
WHERE   obj.is_ms_shipped= 0
        and referenced_id=object_id('TABLE_NAME') /*Where one can Replace table Name*/
        AND obj.type_desc='USER_TABLE'
        ORDER BY TableName,Ref_Object,Ref_Object_Name

但是这个脚本似乎只适用于表所属的数据库。

我想得到指定表名满足的所有数据库的所有对象的指定表名(或者更好的对象)列表:

Database_Name  SchemaName  ObjectName  ObjectKind  

感谢。

3 个答案:

答案 0 :(得分:7)

DECLARE @table_name SYSNAME = N'%';



DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += 'SELECT DISTINCT Database_Name = ''' + QUOTENAME(name) + ''',
        COALESCE(sd.referenced_schema_name +''.'', '''')+ o.name AS TableName,
        r.name AS Ref_Object,
        r.type_desc AS Ref_Object_Name
FROM    ' + QUOTENAME(name) + '.sys.sql_expression_dependencies AS sd
        INNER JOIN ' + QUOTENAME(name) + '.sys.objects AS o
        ON o.object_id = sd.referenced_id
        INNER JOIN ' + QUOTENAME(name) + '.sys.objects AS r
        ON sd.referencing_id = r.object_id
WHERE   o.is_ms_shipped =  0
        and referenced_id = o.object_id
        AND o.type_desc = ''USER_TABLE''
        AND o.name LIKE ''' + @table_name + '''
UNION ALL
'
 FROM sys.databases 
 WHERE database_id BETWEEN 5 AND 32766;

SET @sql = LEFT(@sql, LEN(@sql)-11) 
    + 'ORDER BY Database_Name, TableName,Ref_Object,Ref_Object_Name';

EXEC sp_executesql @sql;

修改

以上内容将查找每个数据库中的所有引用,但不会找到跨数据库引用。它花了一点点玩,输出并不是你想要的,但我认为这使它更加不言自明:

DECLARE @table_name SYSNAME = N'%'; -- find all



CREATE TABLE #d
(
    db SYSNAME, 
    [object_id] INT, 
    sch SYSNAME,
    obj SYSNAME,
    ref_db NVARCHAR(128),
    ref_sch NVARCHAR(128), 
    ref_obj NVARCHAR(128),
    ref_object_id INT,
    type_desc SYSNAME
);

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += 'SELECT ''' + QUOTENAME(name) + ''',
    d.referencing_id,
    QUOTENAME(s.name),
    QUOTENAME(o.name),
    QUOTENAME(d.referenced_database_name),
    QUOTENAME(d.referenced_schema_name),
    QUOTENAME(d.referenced_entity_name),
    d.referenced_id,
    o.type_desc
FROM ' + QUOTENAME(name) 
    + '.sys.sql_expression_dependencies AS d
INNER JOIN ' + QUOTENAME(name) 
    + '.sys.objects AS o
    ON d.referencing_id = o.[object_id]
INNER JOIN ' 
    + QUOTENAME(name) + '.sys.schemas AS s
    ON o.[schema_id] = s.[schema_id]
WHERE d.referenced_entity_name LIKE ''' + @table_name + '''
UNION ALL
'
FROM sys.databases WHERE database_id BETWEEN 5 AND 32766;

SET @sql = LEFT(@sql, LEN(@sql)-11);

INSERT #d EXEC sp_executesql @sql;

SELECT 
    db+'.'+sch+'.'+obj, 
    ' (' + type_desc + ') references => ',
    COALESCE(ref_db, db)+'.'+ref_sch+'.'+ref_obj
    FROM #d;
GO

DROP TABLE #d;
GO

示例输出:

[db1].[dbo].[foo]  (SQL_STORED_PROCEDURE) references =>   [db2].[dbo].[bar]
[db1].[dbo].[xyz]  (SQL_STORED_PROCEDURE) references =>   [db1].[dbo].[table_xyz]

答案 1 :(得分:2)

这应该可以帮助您入门

create table ##tbData (
DatabaseName Varchar(64),
objectName varchar(128),
ObjectKind varchar(128)
)
go

EXEC sp_Msforeachdb "use [?];
       insert ##tbData select db_name(),so.name,so.xtype from sysobjects so"

select * from ##tbdata

基本上,构建一个表和要使用的SQL语句,然后使用未记录的sp_MSforEachdb从每个数据库加载表

答案 2 :(得分:0)

您可以查看sp_MSForeachdb之类的内容,并在每个数据库中调用上述查询。