我可以在SQL Server查询中使用IF语句在多个SQL版本上使用查询吗?

时间:2018-06-22 13:35:48

标签: sql-server

我正在部署一个存储过程,以检查我支持的每台服务器的备份寿命。但是,根据我的编程经验,我知道我可以使用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语句来从运行的版本中调整代码上。

谢谢!

2 个答案:

答案 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;