sp_MSForeachdb插入声明的虚拟表问题

时间:2017-06-07 14:00:10

标签: tsql sql-server-2016 sp-msforeachdb

我在将信息插入@ TBL2表时遇到问题。

我在做错了什么?

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

2 个答案:

答案 0 :(得分:0)

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

  1. 我不认为"使用"声明可以是动态的(可能是错误的)

  2. 在您尝试使用SQL时会声明SQL。

  3. sp_msforeachdb没有文档记录,即使它可以在很多情况下都可以使用,也不应该依赖它。

  4. 我的方法使用sys.databases和字符串连接来生成适当的SQL字符串,以便从除系统数据库之外的所有数据库中的每个表中获取所需的数据,然后将结果执行到临时表中。该方法还假设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
    

答案 1 :(得分:0)

我仍然有一些问题需要解决,但这可能是什么样的

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