首页 > 解决方案 > 如何在实例级别为所有数据库编写所有数据库对象的脚本

问题描述

我尝试使用游标查询我的实例以获取 n 个数据库的所有数据库对象的列表,但无济于事

DROP TABLE IF EXISTS #temp
        SELECT * into #temp from ( select DB_NAME() AS [database_name], sys.schemas.name + '.' + sys.objects.name as [object_name], 
        type as [schema_name], type_desc as [Object_Description]
        FROM    sys.objects 
        INNER JOIN sys.schemas ON sys.objects.schema_id = sys.schemas.schema_id 
        where type in 
        ( 
        'p', 'pc', -- stored procs 
        'v', -- views 
        'tf', 'if', 'ft', -- table-valued functions 
        'fn', 'fs', -- scalar-valued functions 
        'af' -- aggregate functions 
        ) )as [SomeAlias]



--select *from #temp

                        DECLARE @name sysname;
                        DECLARE @sql nvarchar(max) =


         'select databse_name  , schema_name   ,object_name , Object_Description from #temp'

                        DECLARE @theSQL nvarchar(max);

                        DECLARE @results TABLE (
                            [database_name] sysname,
                            [object_name} sysname,
                            [schema_name] sysname,
                            [Object_Description] sysname
                        );

                        DECLARE dbs CURSOR STATIC LOCAL FORWARD_ONLY READ_ONLY 

                        FOR

                        SELECT name 
                        FROM sys.databases;
                        -- you may want to exclude system databases here
                        -- WHERE name NOT IN ('master', 'model', 'msdb', 'tempdb', 'distribution')

                        OPEN dbs;
                        FETCH NEXT FROM dbs INTO @name;

                        WHILE @@FETCH_STATUS = 0
                        BEGIN
                            SET @theSQL = 'EXEC ' + QUOTENAME(@name) + '.sys.sp_executesql @sql';

                            INSERT @results
                            EXEC sys.sp_executesql @theSQL, N'@sql nvarchar(max)', @sql

                            FETCH NEXT FROM dbs INTO @name; 
                        END

                        CLOSE dbs;
                        DEALLOCATE dbs;

                        SELECT *
                        FROM @results;

标签: tsqlsql-server-2016database-cursor

解决方案


有多种方法可以获取您在所有数据库中查找的对象详细信息。我在下面提供了两种解决方案,一种使用cursor问题中尝试的方法,另一种使用更简单的sp_msforeachdb存储过程。

光标方法:

declare @db_nm varchar(250)
    , @sql varchar(1000)

DECLARE @results TABLE (
                            [database_name] sysname,
                            [object_name] sysname,
                            [schema_name] sysname,
                            [Object_Description] sysname
                        );

declare db cursor local
fast_forward for
select db.name
from master.sys.databases as db
where db.name not in ('master', 'tempdb', 'model', 'msdb') --system db you're probably not looking for info in

open db

fetch next from db into @db_nm;

while @@fetch_status = 0
begin

    set @sql = 
        'select ''' + @db_nm + ''' AS [database_name]
        , s.name + ''.'' + o.name as [object_name]
        , type as [schema_name]
        , type_desc as [Object_Description] 
        FROM [' + @db_nm + '].sys.objects as o
        INNER JOIN [' + @db_nm + '].sys.schemas as s ON o.schema_id = s.schema_id  
        where type in (''p'', ''pc'', -- stored procs  
                        ''v'', -- views  
                        ''tf'', ''if'', ''ft'', -- table-valued functions  
                        ''fn'', ''fs'', -- scalar-valued functions  
                        ''af'' -- aggregate functions  
                        ) 
        '

    insert into @results
    exec (@sql)

    fetch next from db into @db_nm;

end

close db

deallocate db

select *
from @results

sp_msforeachdb 方法:

此方法带有该过程未记录的警告。

declare @sql varchar(1000) = 
    '
    if ''?'' not in (''master'', ''tempdb'', ''model'', ''msdb'') --system db youre probably not looking for info in
    begin

        select ''?'' AS [database_name]
        , s.name + ''.'' + o.name as [object_name]
        , type as [schema_name]
        , type_desc as [Object_Description] 
        FROM [?].sys.objects as o
        INNER JOIN [?].sys.schemas as s ON o.schema_id = s.schema_id  
        where type in (''p'', ''pc'', -- stored procs  
                        ''v'', -- views  
                        ''tf'', ''if'', ''ft'', -- table-valued functions  
                        ''fn'', ''fs'', -- scalar-valued functions  
                        ''af'' -- aggregate functions  
                        ) 

    end
    '

DECLARE @results TABLE (
                            [database_name] sysname,
                            [object_name] sysname,
                            [schema_name] sysname,
                            [Object_Description] sysname
                        );

insert into @results
exec master.dbo.sp_msforeachdb @sql

select *
from @results

推荐阅读