跨数据库查询只能单向运行MS SQL Server
我正在尝试将有关索引使用情况的数据插入各种类型的控制数据库中。。我使用的查询如下。。我的问题是,当我从控制数据库执行查询时,让我们调用它A,它返回0个结果,但是如果我从源数据库执行查询,让我们调用它B,它运行得很好。。 为什么? 这种行为在SQL Server 2012开发人员和SQL Server 2008 EE上都可以看到 示例1返回零结果:跨数据库查询只能单向运行MS SQL Server,sql,sql-server,database,sql-server-2008,tsql,Sql,Sql Server,Database,Sql Server 2008,Tsql,我正在尝试将有关索引使用情况的数据插入各种类型的控制数据库中。。我使用的查询如下。。我的问题是,当我从控制数据库执行查询时,让我们调用它A,它返回0个结果,但是如果我从源数据库执行查询,让我们调用它B,它运行得很好。。 为什么? 这种行为在SQL Server 2012开发人员和SQL Server 2008 EE上都可以看到 示例1返回零结果: USE A; INSERT INTO A.dbo.UnusedIndexes SELECT DB_NAME() AS DatabaseNa
USE A;
INSERT INTO A.dbo.UnusedIndexes
SELECT
DB_NAME() AS DatabaseName
, SCHEMA_NAME(o.Schema_ID) AS SchemaName
, OBJECT_NAME(o.object_id) AS TableName
, ix.name AS IndexName
,((SUM(ps.used_page_count)over(partition by ix.index_id))*8)/1024 AS [IndexSizeMB]
, ix_usage_stats.user_updates
, ix_usage_stats.user_seeks + ix_usage_stats.user_scans + ix_usage_stats.user_lookups
AS [User_SeeksScansLookups]
, ix_usage_stats.system_updates
, ix_usage_stats.system_seeks + ix_usage_stats.system_scans + ix_usage_stats.system_lookups
AS [System_SeeksScansLookups]
, NULL as [Drop_Statement]
, NULL as [Create_statement]
,getdate() as [date_added]
FROM B.sys.indexes ix
Left join B.sys.dm_db_index_usage_stats ix_usage_stats
ON ix_usage_stats.object_id = ix.object_id
AND ix_usage_stats.index_id = ix.index_id
INNER JOIN B.sys.objects o ON ix.object_id = o.object_id
JOIN B.sys.dm_db_partition_stats ps ON ps.object_id = ix.object_id AND ix.index_id = ps.index_id
WHERE
ix.name IS NOT NULL -- exclude heaps
AND ix.type <> 1 -- exclude the clustered indexes
AND o.is_ms_shipped = 0 -- exclude system objects
AND o.type NOT IN('F', 'UQ') -- exclude the foreign keys and unique contraints
AND SCHEMA_NAME(o.schema_id) not in ('dbo','stats', 'reporting')
AND (ix_usage_stats.user_seeks = 0 or ix_usage_stats.user_seeks is NULL)
AND (ix_usage_stats.user_scans = 0 or ix_usage_stats.user_scans is null)
AND (ix_usage_stats.user_lookups = 0 or ix_usage_stats.user_lookups is null)
任何帮助都将是巨大的-不幸的是,我无法从数据库B执行此操作,因此简单的解决方案将无法工作
解决了的
我明白了。DB_名称是问题所在。删除它并将其设置为“B”作为databasename修复了该问题。尝试从目标数据库中使用sp_executesql:
USE A;
INSERT INTO A.dbo.UnusedIndexes
EXEC B.sys.sp_executesql N'
SELECT DB_NAME() AS DatabaseName
,SCHEMA_NAME(o.Schema_ID) AS SchemaName
,OBJECT_NAME(o.object_id) AS TableName
,ix.NAME AS IndexName
,((SUM(ps.used_page_count) OVER (PARTITION BY ix.index_id)) * 8) / 1024 AS [IndexSizeMB]
,ix_usage_stats.user_updates
,ix_usage_stats.user_seeks + ix_usage_stats.user_scans + ix_usage_stats.user_lookups AS [User_SeeksScansLookups]
,ix_usage_stats.system_updates
,ix_usage_stats.system_seeks + ix_usage_stats.system_scans + ix_usage_stats.system_lookups AS [System_SeeksScansLookups]
,NULL AS [Drop_Statement]
,NULL AS [Create_statement]
,getdate() AS [date_added]
FROM sys.indexes ix
LEFT JOIN sys.dm_db_index_usage_stats ix_usage_stats
ON ix_usage_stats.object_id = ix.object_id
AND ix_usage_stats.index_id = ix.index_id
INNER JOIN sys.objects o
ON ix.object_id = o.object_id
JOIN sys.dm_db_partition_stats ps
ON ps.object_id = ix.object_id
AND ix.index_id = ps.index_id
WHERE 1 = 1
AND ix.name IS NOT NULL -- exclude heaps
AND ix.type <> 1 -- exclude the clustered indexes
AND o.is_ms_shipped = 0 -- exclude system objects
AND o.type NOT IN(''F'', ''UQ'') -- exclude the foreign keys and unique contraints
AND SCHEMA_NAME(o.schema_id) not in (''dbo'',''stats'', ''reporting'')
AND (
ix_usage_stats.user_seeks = 0
OR ix_usage_stats.user_seeks IS NULL
)
AND (
ix_usage_stats.user_scans = 0
OR ix_usage_stats.user_scans IS NULL
)
AND (
ix_usage_stats.user_lookups = 0
OR ix_usage_stats.user_lookups IS NULL
)
'
您是否了解DB_NAME将返回当前上下文数据库的名称,而不是在FROM和JOIN子句中指定的数据库的名称。在您的第一个示例中,您将返回一个偶数,尽管您正在从Bhave获取数据。您是否尝试将INSERT删除到A.dbo.UnusedIndexes语句中,并验证两个查询是否返回相同的结果?我确实理解这一点-但即使查询中有DB_NAME,它在从yes执行时返回0行-我尝试过执行selects-这一点也不起作用。。但我刚想出来-多亏了你对DB_NAME的评论。。将其设置为常量解决了这个问题。您的表上是否存在某种验证数据库的约束?顺便说一句,我在博客中介绍了一种比动态SQL更好的方法:
USE A;
Select * from B.sys.indexes
USE A;
INSERT INTO A.dbo.UnusedIndexes
EXEC B.sys.sp_executesql N'
SELECT DB_NAME() AS DatabaseName
,SCHEMA_NAME(o.Schema_ID) AS SchemaName
,OBJECT_NAME(o.object_id) AS TableName
,ix.NAME AS IndexName
,((SUM(ps.used_page_count) OVER (PARTITION BY ix.index_id)) * 8) / 1024 AS [IndexSizeMB]
,ix_usage_stats.user_updates
,ix_usage_stats.user_seeks + ix_usage_stats.user_scans + ix_usage_stats.user_lookups AS [User_SeeksScansLookups]
,ix_usage_stats.system_updates
,ix_usage_stats.system_seeks + ix_usage_stats.system_scans + ix_usage_stats.system_lookups AS [System_SeeksScansLookups]
,NULL AS [Drop_Statement]
,NULL AS [Create_statement]
,getdate() AS [date_added]
FROM sys.indexes ix
LEFT JOIN sys.dm_db_index_usage_stats ix_usage_stats
ON ix_usage_stats.object_id = ix.object_id
AND ix_usage_stats.index_id = ix.index_id
INNER JOIN sys.objects o
ON ix.object_id = o.object_id
JOIN sys.dm_db_partition_stats ps
ON ps.object_id = ix.object_id
AND ix.index_id = ps.index_id
WHERE 1 = 1
AND ix.name IS NOT NULL -- exclude heaps
AND ix.type <> 1 -- exclude the clustered indexes
AND o.is_ms_shipped = 0 -- exclude system objects
AND o.type NOT IN(''F'', ''UQ'') -- exclude the foreign keys and unique contraints
AND SCHEMA_NAME(o.schema_id) not in (''dbo'',''stats'', ''reporting'')
AND (
ix_usage_stats.user_seeks = 0
OR ix_usage_stats.user_seeks IS NULL
)
AND (
ix_usage_stats.user_scans = 0
OR ix_usage_stats.user_scans IS NULL
)
AND (
ix_usage_stats.user_lookups = 0
OR ix_usage_stats.user_lookups IS NULL
)
'