尝试运行以下查询:
IF LEFT(CAST(SERVERPROPERTY('ProductVersion') as varchar),2) LIKE '1[2-9]'
SELECT
@@servername AS [Server]
, d.name AS [Database]
, CONVERT(char(10), d.create_date, 121) AS [Created]
, sp.name AS [Owner]
, d.recovery_model_desc AS [Recovery]
, CASE d.state_desc WHEN 'OFFLINE' THEN '***OFFLINE***' ELSE d.state_desc END AS [Status]
, d.user_access_desc AS [Access]
, CASE d.is_read_only WHEN 0 THEN 'READ_WRITE' WHEN 1 THEN 'READ_ONLY' END AS Updateability
, CASE d.is_fulltext_enabled WHEN 0 THEN '' WHEN 1 THEN 'YES' END AS [FullText]
, CASE d.is_auto_create_stats_on WHEN 0 THEN '' WHEN 1 THEN 'YES' END AS [CreateStats]
, CASE d.is_auto_update_stats_on WHEN 0 THEN '' WHEN 1 THEN 'YES' END AS [UpdateStats]
, CASE d.page_verify_option
WHEN 0 THEN '***NONE***'
WHEN 1 THEN '***TORN PAGE DETECTION***' -- outdated in 2005+. Change to checksum.
ELSE d.page_verify_option_desc
END AS [Page Verify]
, d.compatibility_level AS [Level]
, d.target_recovery_time_in_seconds as ckp_s
, d.log_reuse_wait_desc AS [Log Wait]
, d.collation_name AS [Collation]
, CASE d.is_read_committed_snapshot_on WHEN 0 THEN '' WHEN 1 THEN 'YES' END AS [RCS]
, CASE d.snapshot_isolation_state WHEN 0 THEN '' WHEN 1 THEN 'YES' END AS [SI]
, CASE d.is_query_store_on WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' END AS QS
, CASE d.is_auto_close_on WHEN 0 THEN '' WHEN 1 THEN '***YES***' /*always disable auto close*/ END AS [AutoClose]
, CASE d.is_auto_shrink_on WHEN 0 THEN '' WHEN 1 THEN '***YES***' /*always disable auto shrink*/ END AS [AutoShrink]
, d.delayed_durability_desc as [Durability]
FROM sys.databases AS d
LEFT JOIN sys.server_principals AS sp /*get database owner name */ ON sp.sid = d.owner_sid
WHERE d.database_id > 4 -- exclude system DBs
ORDER BY d.name;
ELSE
SELECT
@@servername AS [Server]
, d.name AS [Database]
, CONVERT(char(10), d.create_date, 121) AS [Created]
, sp.name AS [Owner]
, d.recovery_model_desc AS [Recovery]
, CASE d.state_desc WHEN 'OFFLINE' THEN '***OFFLINE***' ELSE d.state_desc END AS [Status]
, d.user_access_desc AS [Access]
, CASE d.is_read_only WHEN 0 THEN 'READ_WRITE' WHEN 1 THEN 'READ_ONLY' END AS Updateability
, CASE d.is_fulltext_enabled WHEN 0 THEN '' WHEN 1 THEN 'YES' END AS [FullText]
, CASE d.is_auto_create_stats_on WHEN 0 THEN '' WHEN 1 THEN 'YES' END AS [CreateStats]
, CASE d.is_auto_update_stats_on WHEN 0 THEN '' WHEN 1 THEN 'YES' END AS [UpdateStats]
, CASE d.page_verify_option
WHEN 0 THEN '***NONE***'
WHEN 1 THEN '***TORN PAGE DETECTION***' -- outdated in 2005+. Change to checksum.
ELSE d.page_verify_option_desc
END AS [Page Verify]
, d.compatibility_level AS [Level]
, 'N/A' AS ckp_s
, d.log_reuse_wait_desc AS [Log Wait]
, d.collation_name AS [Collation]
, CASE d.is_read_committed_snapshot_on WHEN 0 THEN '' WHEN 1 THEN 'YES' END AS [RCS]
, CASE d.snapshot_isolation_state WHEN 0 THEN '' WHEN 1 THEN 'YES' END AS [SI]
, 'N/A' AS QS
, CASE d.is_auto_close_on WHEN 0 THEN '' WHEN 1 THEN '***YES***' /*always disable auto close*/ END AS [AutoClose]
, CASE d.is_auto_shrink_on WHEN 0 THEN '' WHEN 1 THEN '***YES***' /*always disable auto shrink*/ END AS [AutoShrink]
, 'N/A' AS [Durability]
FROM sys.databases AS d
LEFT JOIN sys.server_principals AS sp /*get database owner name */ ON sp.sid = d.owner_sid
WHERE d.database_id > 4 -- exclude system DBs
ORDER BY d.name;
问题出在SQL Server 2005/2008/2012上。列target_recovery_time_in_seconds, is_query_store_on, and delayed_durability_desc
不存在于sys.databases表中。
顶部的IF语句查找它的SQL Server版本。如果是2014年以上,请使用这3列运行查询。如果没有,请运行没有这3列的查询。我在其他查询中使用了这个逻辑并且它可以工作,但在这种情况下却没有。我收到以下错误:
Msg 207,Level 16,State 1,Line 20
列名称无效' target_recovery_time_in_seconds'。Msg 207,Level 16,State 1,Line 25
列名称无效' is_query_store_on'。Msg 207,Level 16,State 1,Line 25
列名称无效' is_query_store_on'。Msg 207,Level 16,State 1,Line 28
列名称无效' delayed_durability_desc' .`
我的问题是为什么SQL Server没有读取IF语句?如果是这样,它将跳过3列的查询并运行没有它的那个。
答案 0 :(得分:2)
执行SQL查询时,首先评估整个事物。因此,当您在SQL2012或更早版本上运行它时,这些字段不存在,因此您的查询无效,因为这些字段不存在,即使该部分不会被执行。
你可以尝试使用一些动态的sql来解决这个问题 - 将整个命令构建成一个包含你需要的各种元素的字符串,并使用sp_executesql
例如:
declare @sql nvarchar(4000)
select @sql = 'SELECT @@servername AS [Server], d.name AS [Database] '
-- some fields omitted here for brevity
IF LEFT(CAST(SERVERPROPERTY('ProductVersion') as varchar),2) LIKE '1[2-9]'
begin
select @sql = @sql + ', CASE d.is_query_store_on WHEN 0 THEN ''NO'' WHEN 1 THEN ''YES'' END AS QS '
end
else
begin
select @sql = @sql + ', ''N/A'' as QS '
end
select @sql = @sql + ' FROM sys.databases AS d LEFT JOIN sys.server_principals AS sp /*get database owner name */ ON sp.sid = d.owner_sid WHERE d.database_id > 4 -- exclude system DBs ORDER BY d.name; '
exec sp_executesql @sql
答案 1 :(得分:2)
SQL Server将尝试编译批处理中的所有语句(除非它们引用不存在的整个对象 - 编译将被延迟。引用现有对象的缺失列不会导致延迟编译。)。
虽然只有一个查询可以在您定位的所有版本中运行,但有一个trick you can use,并且避免使用动态SQL。
以下<--
标记的列将从sys.databases
解析(如果它们存在于此处),或者回退到dummy
派生表失败的列。
WITH d
AS (SELECT x.*
FROM (SELECT 'N/A', 'N/A', 'N/A')
AS dummy (is_query_store_on, delayed_durability_desc, target_recovery_time_in_seconds)
CROSS APPLY (SELECT d.collation_name,
d.compatibility_level,
d.create_date,
d.database_id,
delayed_durability_desc, /* <-- resolved from d or dummy */
d.is_auto_close_on,
d.is_auto_create_stats_on,
d.is_auto_shrink_on,
d.is_auto_update_stats_on,
d.is_fulltext_enabled,
is_query_store_on, /* <-- resolved from d or dummy */
d.is_read_committed_snapshot_on,
d.is_read_only,
d.log_reuse_wait_desc,
d.name,
d.owner_sid,
d.page_verify_option,
d.page_verify_option_desc,
d.recovery_model_desc,
d.snapshot_isolation_state,
d.state_desc,
target_recovery_time_in_seconds, /* <-- resolved from d or dummy */
d.user_access_desc
FROM sys.databases AS d) AS x)
SELECT
@@servername AS [Server]
, d.name AS [Database]
, CONVERT(char(10), d.create_date, 121) AS [Created]
, sp.name AS [Owner]
, d.recovery_model_desc AS [Recovery]
, CASE d.state_desc WHEN 'OFFLINE' THEN '***OFFLINE***' ELSE d.state_desc END AS [Status]
, d.user_access_desc AS [Access]
, CASE d.is_read_only WHEN 0 THEN 'READ_WRITE' WHEN 1 THEN 'READ_ONLY' END AS Updateability
, CASE d.is_fulltext_enabled WHEN 0 THEN '' WHEN 1 THEN 'YES' END AS [FullText]
, CASE d.is_auto_create_stats_on WHEN 0 THEN '' WHEN 1 THEN 'YES' END AS [CreateStats]
, CASE d.is_auto_update_stats_on WHEN 0 THEN '' WHEN 1 THEN 'YES' END AS [UpdateStats]
, CASE d.page_verify_option
WHEN 0 THEN '***NONE***'
WHEN 1 THEN '***TORN PAGE DETECTION***' -- outdated in 2005+. Change to checksum.
ELSE d.page_verify_option_desc
END AS [Page Verify]
, d.compatibility_level AS [Level]
, d.target_recovery_time_in_seconds as ckp_s
, d.log_reuse_wait_desc AS [Log Wait]
, d.collation_name AS [Collation]
, CASE d.is_read_committed_snapshot_on WHEN 0 THEN '' WHEN 1 THEN 'YES' END AS [RCS]
, CASE d.snapshot_isolation_state WHEN 0 THEN '' WHEN 1 THEN 'YES' END AS [SI]
, CASE d.is_query_store_on WHEN 'false' THEN 'NO' WHEN 'true' THEN 'YES' ELSE 'N/A' END AS QS
, CASE d.is_auto_close_on WHEN 0 THEN '' WHEN 1 THEN '***YES***' /*always disable auto close*/ END AS [AutoClose]
, CASE d.is_auto_shrink_on WHEN 0 THEN '' WHEN 1 THEN '***YES***' /*always disable auto shrink*/ END AS [AutoShrink]
, d.delayed_durability_desc as [Durability]
FROM d
LEFT JOIN sys.server_principals AS sp /*get database owner name */ ON sp.sid = d.owner_sid
WHERE d.database_id > 4 -- exclude system DBs
ORDER BY d.name;