2017-08-04 3 views
0

Ich habe eine Abfrage geschrieben, die SQL AlwaysON-Integritätsinformationen abruft. Sie müssen nur noch eine where-Klausel am Ende hinzufügen, um AvailabilityGroupName und DatabaseName zu filtern. Es funktioniert, wenn ich die Abfrage einfüge: 'Wählen Sie * aus den Ergebnissen, wo AvailabilityGroupName =' LAB-VIP-USADB 'UND DatabaseName =' CPS ''. Wenn ich jedoch die Abfrage in einer nvarchar-Variablen @ sql am Anfang und später die in der Variablen gespeicherte Abfrage ausführe, habe ich die Fehlermeldung "Falsche Syntax neben dem Schlüsselwort 'EXEC'" erhalten. Der Grund, warum ich die Abfrage parametrisieren möchte, ist, dass eine Verfügbarkeitsgruppe mehrere Datenbanken enthalten könnte. Die parametrisierte Eingabe kommt von PRTG, so dass sie die Verfügbarkeitsgruppe für diese spezifische Datenbank abfragt.Dynamic SQL, parametrisierte Abfrage

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)

Antwort

1

Sie es nicht tun, sind CTE Tabellen auf den nächsten SQL-Befehl nur zugänglich.

Wenn Sie den Befehl EXEC (@sql) intern ausführen, erstellt SQL mehr als einen Befehl.

Versuchen Sie, den gesamten Code in eine Variable zu verschieben.

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) 

ich tryed diesen Befehl in meiner Umgebung laufen und ich habe den Fehler unten, weil ich es nicht über die Tische.

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