如何排除主数据库

问题描述 投票:0回答:2

我创建了以下查询,该查询将从所有数据库中获取数据。当我执行查询时,我得到错误的无效列ID。我已经调查并发现主数据库中列出了表tbl_table_A(示例),并且该表没有列ID。我已排除了该数据库主数据库,但不确定为什么查询仍在调用主数据库。请告知

查询:

CREATE TABLE ##tbl_data 

(
 [database_name] NVARCHAR(500), 
 id              INT, 
 last_run        DATETIME, 
 [next_run]      DATETIME, 
 last_run_status NVARCHAR(500) 

)



DECLARE @StartDate NVARCHAR(MAX)
DECLARE @EndDate NVARCHAR(MAX)
DECLARE @strSQL NVARCHAR(MAX)

SET @StartDate  = '10-Dec-2019 00:12:59'
SET @EndDate    = '10-Dec-2019 00:17:59'


SET @strSQL =

'
USE [?]

IF ''?'' <> ''master'' AND ''?'' <> ''model'' AND ''?'' <> ''msdb'' AND ''?'' <> ''tempdb''

BEGIN

IF OBJECT_ID(''tbl_table_A'') IS  NULL
RETURN;

insert into ##tbl_data 

SELECT ''?'', id,last_run,next_run,last_run_status

    FROM dbo.tbl_table_A nolock  

WHERE last_run  between cast ('''+@StartDate+''' as Datetime2) and cast ('''+@EndDate+''' as Datetime2)  


END'

EXEC dbo.sp_msforeachdb @strSQL

Select * from ##tbl_data
Drop table ##tbl_data
sql-server tsql dynamic-sql
2个回答
1
投票

我已经排除了该数据库主服务器,但不确定为什么查询仍然存在调用主数据库

[否,您的代码不会“调用” master。这是您使用打印而不是插入的代码。这样,您可以查看究竟检查了什么db,以及那里是否有您的表:

declare @strSQL NVARCHAR(MAX)
SET @strSQL =

'
USE [?]

IF ''?'' <> ''master'' AND ''?'' <> ''model'' AND ''?'' <> ''msdb'' AND ''?'' <> ''tempdb''

BEGIN
print ''?''

IF OBJECT_ID(''tbl_table_A'') IS  NULL
begin
    print ''there is no table tbl_table_A''
    print ''----------------''
    RETURN;
end

    print ''***** THERE IS table tbl_table_A *****''
    print ''----------------''

END'

EXEC dbo.sp_msforeachdb @strSQL

0
投票

我一直喜欢对这些类型的问题采用不同的方法。首先,我真的不喜欢游标,您真的不需要这里的游标。另外,sp_msforeachdb不仅未公开,而且还存在一些问题。有时会跳过数据库,而且似乎没有人真正知道为什么。亚伦·伯特兰(Aaron Bertrand)对此进行了讨论,并在此提供了更好的选择。 https://sqlblog.org/2010/12/29/a-more-reliable-and-more-flexible-sp_msforeachdb

我更喜欢做下面的事情。没有循环,也不会遇到像跳表这样的怪异行为。它还不需要可能存在严重的并发问题的全局临时表。这需要两个动态sql语句。第一个获取具有要查找表的数据库列表。然后,我们使用该数据针对要搜索的数据库列表生成动态sql语句。

if OBJECT_ID('tempdb..#Databases') is not null
    drop table #Databases

DECLARE @StartDate NVARCHAR(MAX)
    , @EndDate NVARCHAR(MAX)
    , @strSQL NVARCHAR(MAX)

SELECT @StartDate  = '20191210 00:12:59'
    , @EndDate    = '20191210 00:17:59'
    , @strSQL = ''

declare @TableName sysname = 'tbl_table_A'

select @strSQL = @strSQL + 'select ''' + d.name + ''' from ' + quotename(d.name) + '.sys.tables where name = ''' + @TableName + ''' union all '
from sys.databases d

select @strSQL = left(@strSQL, len(@strSql) - 10) --this removes the last union all

CREATE TABLE #Databases 
(
    DatabaseName sysname
)

--select @strSQL

insert #Databases
(
    DatabaseName
)
exec sp_executesql @strSQL

set @strSQL = ''

select @strSQL = @strSQL + 'select ''' + d.DatabaseName + ''',  id, last_run, next_run, last_run_status from ' + quotename(d.DatabaseName) + '.dbo.' + @TableName + ' where last_run between @_StartDate and @_EndDate union all '
from #Databases d

select @strSQL = left(@strSQL, len(@strSql) - 10)

--select @strSQL

exec sp_executesql @strSQL, N'@_StartDate datetime, @_EndDate datetime', @_StartDate = @StartDate, @_EndDate = @EndDate
© www.soinside.com 2019 - 2024. All rights reserved.