我正在部署一个存储过程,以检查我支持的每台服务器的备份寿命。但是,根据我的编程经验,我知道我可以使用IF语句来检查我运行的版本,从而添加或删除部分代码。
这是代码:
SELECT DISTINCT
SUBSTRING(s.name,1,50) AS 'DATABASE Name',
b.backup_start_date AS 'Full DB Backup Status',
c.backup_start_date AS 'Differential DB Backup Status',
d.backup_start_date AS 'Transaction Log Backup Status',
DATEDIFF(HOUR, b.backup_start_date, GETDATE()) AS 'Age Full Backup',
--Get number hours since last full backup
ISNULL(DATEDIFF(HOUR, c.backup_start_date, GETDATE()), 0) AS 'Age Diff Backup',
--Get number hours since last diff backup
ISNULL(DATEDIFF(HOUR, d.backup_start_date, GETDATE()), 0) AS 'Age Tlog Backup',
--Get number hours since last tlog backup
s2.state_desc AS 'Status',
s2.recovery_model
FROM
MASTER..sysdatabases s
LEFT OUTER JOIN
msdb..backupset b ON s.name = b.database_name
AND b.backup_start_date = (SELECT MAX(backup_start_date) AS 'Full DB Backup Status'
FROM msdb..backupset
WHERE database_name = b.database_name
AND TYPE = 'D') -- full database backups only, not log backups
LEFT OUTER JOIN
master.sys.databases s2 ON s2.name = b.database_name
LEFT OUTER JOIN
msdb..backupset c ON s.name = c.database_name
AND c.backup_start_date = (SELECT MAX(backup_start_date) 'Differential DB Backup Status'
FROM msdb..backupset
WHERE database_name = c.database_name
AND TYPE = 'I')
LEFT OUTER JOIN
msdb..backupset d ON s.name = d.database_name
AND d.backup_start_date = (SELECT MAX(backup_start_date) 'Transaction Log Backup Status'
FROM msdb..backupset
WHERE database_name = d.database_name
AND TYPE = 'L')
WHERE
s.name != 'tempdb'
AND s.name NOT IN ('master', 'model', 'msdb')
AND s.name NOT LIKE '%TMP[_]%'
我想知道是否可以在最后将这部分添加到WHERE子句中:
AND dbid NOT IN (SELECT database_id
FROM master.sys.dm_hadr_database_replica_states AS DRS
INNER JOIN sys.dm_hadr_availability_replica_states AS ARS ON ARS.replica_id = DRS.replica_id
WHERE ARS.is_local = 1 AND role_desc = 'SECONDARY')
但仅适用于高于或等于2012的SQL Server吗?自AlwaysOn于2012年推出以来,此代码在2008 R2及更低版本上会产生错误。
到目前为止,我有这个IF语句,用于检查运行良好的版本:
IF CONVERT(int, SUBSTRING(@@VERSION, 22, 4)) >= 2012
PRINT 'true'
ELSE
PRINT 'false'
我知道我可以删除代码并创建我的存储过程,但是我想知道是否可以像在C#或JavaScript中那样放置IF语句来从运行的版本中调整代码上。
谢谢!
答案 0 :(得分:0)
您可以执行以下操作:
DECLARE @Version int
SET @Version = (select CONVERT(int,substring(@@Version,22,4)))
DECLARE @SQL nvarchar(max)
DECLARE @WHERECLAUSE nvarchar(max)
DECLARE @SQLNESTED nvarchar(max)
SET @SQL = 'SELECT DISTINCT SUBSTRING(s.name,1,50) AS [DATABASE Name]
, b.backup_start_date AS [Full DB Backup Status]
, c.backup_start_date AS [Differential DB Backup Status]
, d.backup_start_date AS [Transaction Log Backup Status]
, DATEDIFF(HOUR, b.backup_start_date,GETDATE()) AS [Age Full Backup] --Get number hours since last full backup
, isnull(DATEDIFF(HOUR, c.backup_start_date,GETDATE()),0) AS [Age Diff Backup] --Get number hours since last diff backup
, isnull(DATEDIFF(HOUR, d.backup_start_date,GETDATE()),0) AS [Age Tlog Backup] --Get number hours since last tlog backup
, s2.state_desc AS [Status]
, s2.recovery_model
FROM MASTER..sysdatabases s
LEFT OUTER JOIN
msdb..backupset b ON s.name = b.database_name
AND b.backup_start_date =(
SELECT MAX(backup_start_date) AS [Full DB Backup Status]
FROM msdb..backupset
WHERE database_name = b.database_name
AND TYPE = ''D'') -- full database backups only, not log backups
LEFT OUTER JOIN master.sys.databases s2 ON s2.name=b.database_name
LEFT OUTER JOIN msdb..backupset c ON s.name = c.database_name AND c.backup_start_date = (
SELECT MAX(backup_start_date) as [Differential DB Backup Status]
FROM msdb..backupset
WHERE database_name = c.database_name AND TYPE = ''I'')
LEFT OUTER JOIN msdb..backupset d ON s.name = d.database_name AND d.backup_start_date = (
SELECT MAX(backup_start_date) as [Transaction Log Backup Status]
FROM msdb..backupset
WHERE database_name = d.database_name AND TYPE = ''L'')
WHERE s.name != ''tempdb'' AND s.name NOT IN(''master'',''model'',''msdb'') AND s.name NOT LIKE ''%TMP[_]%'''
SET @WHERECLAUSE = 'AND dbid NOT IN (
SELECT database_id
FROM master.sys.dm_hadr_database_replica_states AS DRS
INNER JOIN sys.dm_hadr_availability_replica_states AS ARS
ON ARS.replica_id = DRS.replica_id
WHERE ARS.is_local = 1 AND role_desc = ''SECONDARY'')'
IF(@Version >= 2012)
BEGIN
SET @SQLNESTED = @SQL + ' '+ @WHERECLAUSE
exec (@SQLNESTED)
--PRINT @SQLNESTED
END
ELSE
BEGIN
SET @SQLNESTED = @SQL
exec (@SQLNESTED)
--PRINT @SQLNESTED
END
答案 1 :(得分:0)
要解释我的意思,这是一种实现您所追求的目标的方法:
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'
SELECT DISTINCT
SUBSTRING(s.name, 1, 50) AS ''DATABASE Name'',
b.backup_start_date AS ''Full DB Backup Status'',
c.backup_start_date AS ''Differential DB Backup Status'',
d.backup_start_date AS ''Transaction Log Backup Status'',
DATEDIFF(HOUR, b.backup_start_date, GETDATE()) AS ''Age Full Backup'', --Get number hours since last full backup
ISNULL(DATEDIFF(HOUR, c.backup_start_date, GETDATE()), 0) AS ''Age Diff Backup'', --Get number hours since last diff backup
ISNULL(DATEDIFF(HOUR, d.backup_start_date, GETDATE()), 0) AS ''Age Tlog Backup'', --Get number hours since last tlog backup
s2.state_desc AS ''Status'',
s2.recovery_model
FROM master..sysdatabases s
LEFT OUTER JOIN msdb..backupset b ON s.name = b.database_name
AND b.backup_start_date = (SELECT MAX(backup_start_date) AS ''Full DB Backup Status''
FROM msdb..backupset
WHERE database_name = b.database_name
AND type = ''D'') -- full database backups only, not log backups
LEFT OUTER JOIN master.sys.databases s2 ON s2.name = b.database_name
LEFT OUTER JOIN msdb..backupset c ON s.name = c.database_name
AND c.backup_start_date = (SELECT MAX(backup_start_date) ''Differential DB Backup Status''
FROM msdb..backupset
WHERE database_name = c.database_name
AND type = ''I'')
LEFT OUTER JOIN msdb..backupset d ON s.name = d.database_name
AND d.backup_start_date = (SELECT MAX(backup_start_date) ''Transaction Log Backup Status''
FROM msdb..backupset
WHERE database_name = d.database_name
AND type = ''L'')
WHERE s.name != ''tempdb''
AND s.name NOT IN (''master'', ''model'', ''msdb'')
AND s.name NOT LIKE ''%TMP[_]%''';
IF CONVERT(int, SUBSTRING(@@VERSION, 22, 4)) >= 2012 BEGIN
SET @SQL = N'
AND dbid NOT IN (SELECT database_id
FROM master.sys.dm_hadr_database_replica_states AS DRS
INNER JOIN sys.dm_hadr_availability_replica_states AS ARS ON ARS.replica_id = DRS.replica_id
WHERE ARS.is_local = 1
AND role_desc = ''SECONDARY'')';
END
SET @SQL = @SQL + N';';
PRINT @SQL; --Your debugging best friend
EXEC sp_executesql @SQL;