2017-08-04 154 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'.