sp_MSForeachdb 插入声明的虚拟 table 问题

sp_MSForeachdb inserting into declared virtual table issue

我在获取信息以插入@TBL2 Table 时遇到问题。

我做错了什么?

DECLARE @command varchar(1000) 
DECLARE @SQLStatment varchar(1000) 

DECLARE @TBL2 table (
                    Database_Name nvarchar(max),
                    SI_SITE nvarchar(max),
                    SI_DB_USER nvarchar(max)
                    )  

SELECT @command = 'IF ''?'' NOT IN(''master'', ''model'', ''msdb'', ''tempdb'') BEGIN USE ? insert into @tbl2  EXEC('+ @SQLStatment +') END'

set @SQLStatment =  'select top 1 Db_Name() as Database_Name, SI_SITE, SI_DB_USER from t_site'

EXEC master.. sp_MSForeachdb @command

select * from @TBL2

试试这个: 您采用的方法存在几个问题:

  1. 我不认为 "USE" 语句可以是动态的(可能是错误的)

  2. SQL 是在您尝试使用它之后声明的。

  3. sp_msforeachdb 未记录且不应依赖,即使它可以在许多情况下工作。

我的方法是使用sys.databases和字符串连接生成合适的SQL字符串来从除系统数据库以外的所有数据库中的每个table中获取你想要的数据,然后执行结果转换为临时 table。该方法还采用 dbo 模式。必要时进行调整。

declare @SQL nvarchar(max)
set @SQL = ''

Create Table #TBL2 (
                    Database_Name nvarchar(max),
                    SI_SITE nvarchar(max),
                    SI_DB_USER nvarchar(max)
                    )

Select @SQL = @SQL + 'INSERT INTO #TBL2 (Database_Name, SI_SITE, SI_DB_USER) select top 1 ''' + name + ''' as Database_Name, SI_SITE, SI_DB_USER from ' + name + '..t_site;' + char(13)  
From sys.databases
Where name not in ('master', 'model', 'msdb', 'tempdb') 

print @SQL                      
exec sp_executesql @SQL

Select * From #TBL2

drop table #TBL2

我还有一些问题需要解决,但这就是它的样子

declare @SQL nvarchar(max)
set @SQL = ''

Create Table #TBL3 (
                Server_Name nvarchar(max),
                Database_Name nvarchar(max),
                DB_Owner nvarchar(max),
                SI_SITE nvarchar(max),
                SI_DB_USER nvarchar(max),
                DB_Creation_date nvarchar(max),
                DB_state nvarchar(max),
                DB_SQL_version nvarchar(max)
                )

Select @SQL = @SQL + 'INSERT INTO #TBL3 
(
     Server_Name
    ,[Database_Name]
    ,[DB_Owner]
    ,[DB_Creation_Date]
    ,[DB_State]
    ,[DB_SQL_Version]       
    ,[SI_SITE]
    ,[SI_DB_USER]
)

SELECT 
     Server_Name
    ,quotename(''' + name + ''')
    ,[DB_Owner]
    ,[DB_Creation_date]
    ,[DB_state]
    ,[DB_SQL_version]       
    ,[SI_SITE]
    ,[SI_DB_USER]

From( SELECT TOP 1
         [SI_SITE]
        ,[SI_DB_USER]
      From  [' + name + ']..[t_site]) Q1,

    ( SELECT
        @@SERVERNAME as [Server_Name]
        ,suser_sname(owner_sid) as [DB_Owner]
        ,[Create_Date] as [DB_Creation_date]
        ,[state_desc] as [DB_state]
        ,case  [compatibility_level] 
        when 80 then ''SQL Server 2000''  when 90 then ''SQL Server 2005''  when 100 then ''SQL Server 2008''   when 110 then ''SQL Server 2012''   when 120 then ''SQL Server 2014''   when 130 then ''SQL Server 2016''   when 140 then ''SQL Server 2017''   else cast(compatibility_level as varchar(100)) end as DB_SQL_version
    from [sys].[databases]
    where [name] = ''' + name + '''
    ) Q2;' + char(13)

    From sys.databases
Where name not in ('master', 'model', 'msdb', 'tempdb') 
and name not in ('DBX') -- where [T_site] table does not exist  
and name not in ('DBY')  -- offline, need offline clause added


    print @SQL   

    exec sp_executesql @SQL

    Select * From #TBL3

    DROP TABLE #TBL3