Вставка 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 ответа
Попробуйте это: Есть несколько проблем с подходом, который вы используете:
Я не думаю, что выражение "USE" может быть динамическим (может быть ошибочным)
SQL объявляется после того, как вы пытаетесь его использовать.
sp_msforeachdb недокументирован и на него не следует полагаться, хотя он может работать во многих обстоятельствах.
Мой подход использует sys.database и конкатенацию строк, чтобы сгенерировать соответствующую строку 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
У меня все еще есть некоторые проблемы, которые нужно решить, но вот как это может выглядеть
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