2017-08-04 91 views
0

我写了一个查询,它提取SQL AlwaysON健康信息。剩下的唯一事情就是在最后添加一个where子句以过滤AvailabilityGroupName和DatabaseName。当我在查询中输入时:'select * from results where AvailabilityGroupName ='LAB-VIP-USADB'和DatabaseName ='CPS''。但是,当我将查询存储在变量nvarchar变量@sql中,然后执行存储在变量中的查询时,我收到错误消息“关键字'EXEC'附近的语法错误”。我想参数化查询的原因是一个可用性组可能包含多个数据库。参数化输入将来自PRTG,以便它查询该特定数据库的可用性组。动态SQL,参数化查询

DECLARE @sql NVARCHAR(MAX) 
 

 
SET @sql='SELECT * FROM Results WHERE AvailabilityGroupName = ''LAB-VIP-USADB'' AND DatabaseName = ''CPS''' 
 
--select @sql 
 
; 
 
WITH basicaginfo AS(
 
SELECT 
 
     
 
     ag.name AS AvailabilityGroupName, 
 
     cs.replica_server_name AS NodeName, 
 
     rs.role_desc, 
 
     rs.synchronization_health_desc, 
 
     DB_NAME(drs.database_id) AS DatabaseName 
 
     
 

 

 
FROM 
 
     sys.availability_groups ag 
 
        JOIN 
 
     sys.dm_hadr_availability_replica_cluster_states cs on ag.group_id = cs.group_id 
 
        JOIN 
 
     sys.dm_hadr_availability_replica_states rs ON (ag.group_id=rs.group_id AND cs.replica_id = rs.replica_id) 
 
        JOIN 
 
     sys.dm_hadr_database_replica_states drs ON (ag.group_id=drs.group_id AND cs.replica_id = drs.replica_id) 
 
       
 

 
\t \t \t \t \t), 
 

 
    
 
     AG_Stats AS 
 
        (
 
        SELECT AR.replica_server_name, 
 
           HARS.role_desc, 
 
           Db_name(DRS.database_id) [DBName], 
 
           DRS.last_commit_time 
 
        FROM sys.dm_hadr_database_replica_states DRS 
 
        INNER JOIN sys.availability_replicas AR ON DRS.replica_id = AR.replica_id 
 
        INNER JOIN sys.dm_hadr_availability_replica_states HARS ON AR.group_id = HARS.group_id 
 
          AND AR.replica_id = HARS.replica_id 
 
        ), 
 
     Pri_CommitTime AS 
 
        (
 
        SELECT replica_server_name 
 
           , DBName 
 
           , last_commit_time 
 
        FROM AG_Stats 
 
        WHERE role_desc = 'PRIMARY' 
 
        ), 
 
     Sec_CommitTime AS 
 
        (
 
        SELECT replica_server_name 
 
           , DBName 
 
           , last_commit_time 
 
        FROM AG_Stats 
 
        WHERE role_desc = 'SECONDARY' 
 
        ), 
 
\t \t Results AS 
 
\t \t \t \t \t (
 
\t \t \t \t \t SELECT 
 
\t \t \t \t \t \t AvailabilityGroupName, 
 
\t \t \t \t \t \t DatabaseName, 
 
\t \t \t \t \t \t [LAB-SCB-SQL01], 
 
\t \t \t \t \t \t [LAB-SCB-SQL02], 
 
\t \t \t \t \t \t [LAB-LAS-SQL01], 
 
\t \t \t \t \t \t [LAB-LAS-SQL02], 
 
\t \t \t \t \t \t [Max_Sync_Lag_Secs] 
 
\t \t \t \t \t FROM(
 
\t \t \t \t \t \t \t SELECT 
 
\t \t \t \t \t \t \t \t bb.AvailabilityGroupName, 
 
\t \t \t \t \t \t \t \t bb.DatabaseName, 
 
\t \t \t \t \t \t \t \t bb.NodeName, 
 
\t \t \t \t \t \t \t \t bb.synchronization_health_desc, 
 
\t \t \t \t \t \t \t \t MAX(DATEDIFF(ss,s.last_commit_time,p.last_commit_time)) OVER (PARTITION BY NULL) AS [Max_Sync_Lag_Secs] 
 
    
 
\t \t \t \t \t \t \t FROM 
 
\t \t \t \t \t \t \t \t basicaginfo bb 
 
\t \t \t \t \t \t \t \t \t LEFT JOIN 
 
\t \t \t \t \t \t \t \t Pri_CommitTime p ON p.DBName=bb.DatabaseName 
 
\t \t \t \t \t \t \t \t \t LEFT JOIN 
 
\t \t \t \t \t \t \t \t Sec_CommitTime s ON bb.NodeName = s.replica_server_name 
 
\t \t \t \t \t \t) AS Data 
 
\t \t \t \t \t PIVOT(
 

 
\t \t \t \t \t \t \t MAX(synchronization_health_desc) FOR [NodeName] IN([LAB-SCB-SQL01], [LAB-SCB-SQL02], [LAB-LAS-SQL01], [LAB-LAS-SQL02]) 
 
\t \t \t \t \t \t ) AS PivotedData 
 
\t \t \t \t \t) 
 
EXEC(@sql)

回答

1

你不能做到这一点,CTE表只对下一个SQL命令进行访问。

当您在内部执行命令EXEC(@sql)时,SQL将执行多个命令。

尝试将所有代码移至变量。

DECLARE @sql NVARCHAR(MAX) 

SET @sql=N'WITH basicaginfo AS(
SELECT 

     ag.name AS AvailabilityGroupName, 
     cs.replica_server_name AS NodeName, 
     rs.role_desc, 
     rs.synchronization_health_desc, 
     DB_NAME(drs.database_id) AS DatabaseName 



FROM 
     sys.availability_groups ag 
        JOIN 
     sys.dm_hadr_availability_replica_cluster_states cs on ag.group_id = cs.group_id 
        JOIN 
     sys.dm_hadr_availability_replica_states rs ON (ag.group_id=rs.group_id AND cs.replica_id = rs.replica_id) 
        JOIN 
     sys.dm_hadr_database_replica_states drs ON (ag.group_id=drs.group_id AND cs.replica_id = drs.replica_id) 


        ), 


     AG_Stats AS 
        (
        SELECT AR.replica_server_name, 
           HARS.role_desc, 
           Db_name(DRS.database_id) [DBName], 
           DRS.last_commit_time 
        FROM sys.dm_hadr_database_replica_states DRS 
        INNER JOIN sys.availability_replicas AR ON DRS.replica_id = AR.replica_id 
        INNER JOIN sys.dm_hadr_availability_replica_states HARS ON AR.group_id = HARS.group_id 
          AND AR.replica_id = HARS.replica_id 
        ), 
     Pri_CommitTime AS 
        (
        SELECT replica_server_name 
           , DBName 
           , last_commit_time 
        FROM AG_Stats 
        WHERE role_desc = ''PRIMARY'' 
        ), 
     Sec_CommitTime AS 
        (
        SELECT replica_server_name 
           , DBName 
           , last_commit_time 
        FROM AG_Stats 
        WHERE role_desc = ''SECONDARY'' 
        ), 
     Results AS 
        (
        SELECT 
         AvailabilityGroupName, 
         DatabaseName, 
         [LAB-SCB-SQL01], 
         [LAB-SCB-SQL02], 
         [LAB-LAS-SQL01], 
         [LAB-LAS-SQL02], 
         [Max_Sync_Lag_Secs] 
        FROM(
          SELECT 
           bb.AvailabilityGroupName, 
           bb.DatabaseName, 
           bb.NodeName, 
           bb.synchronization_health_desc, 
           MAX(DATEDIFF(ss,s.last_commit_time,p.last_commit_time)) OVER (PARTITION BY NULL) AS [Max_Sync_Lag_Secs] 

          FROM 
           basicaginfo bb 
            LEFT JOIN 
           Pri_CommitTime p ON p.DBName=bb.DatabaseName 
            LEFT JOIN 
           Sec_CommitTime s ON bb.NodeName = s.replica_server_name 
         ) AS Data 
        PIVOT(

          MAX(synchronization_health_desc) FOR [NodeName] IN([LAB-SCB-SQL01], [LAB-SCB-SQL02], [LAB-LAS-SQL01], [LAB-LAS-SQL02]) 
         ) AS PivotedData 
        ) 
        SELECT * FROM Results WHERE AvailabilityGroupName = ''LAB-VIP-USADB'' AND DatabaseName = ''CPS''' 
EXEC(@sql) 

我尝试了在我的环境中运行这个命令,我得到了错误,因为我没有它的表。

Msg 208, Level 16, State 1, Line 1 
Invalid object name 'sys.availability_groups'.