Traitement des instructions qui génèrent des messages
Les options STATISTICS TIME et STATISTICS IO de l'instruction Transact-SQL SET sont utilisées pour obtenir des informations qui aident au diagnostic des requêtes longues. Les versions antérieures de SQL Server prennent aussi en charge l'option SHOWPLAN pour analyser les plans de requête. Une application ODBC peut définir ces options en exécutant les instructions suivantes :
SQLExecDirect(hstmt, "SET SHOWPLAN ON", SQL_NTS);
SQLExecDirect(hstmt, "SET STATISTICS TIME ON", SQL_NTS90
);
SQLExecDirect(hstmt, "SET STATISTICS IO ON", SQL_NTS);
Quand SET STATISTICS TIME ou SET SHOWPLAN ont la valeur ON, SQLExecute et SQLExecDirect retournent SQL_SUCCESS_WITH_INFO, et, à ce stade, l'application peut extraire la sortie SHOWPLAN ou STATISTICS TIME en appelant SQLGetDiagRec jusqu'à ce que SQL_NO_DATA soit retourné. Chaque ligne des données SHOWPLAN est retournée au format suivant :
szSqlState="01000", *pfNativeError=6223,
szErrorMsg="[Microsoft][SQL Server Native Client][SQL Server]
Table Scan"
SQL Server version 7.0 a remplacé l'option SHOWPLAN par SHOWPLAN_ALL et SHOWPLAN_TEXT, qui retournent l'une et l'autre la sortie comme jeu de résultats, et non comme ensemble de messages.
Chaque ligne de STATISTICS TIME est retournée au format suivant :
szSqlState="01000", *pfNativeError= 3613,
szErrorMsg="[Microsoft][SQL Server Native Client][SQL Server]
SQL Server Parse and Compile Time: cpu time = 0 ms."
La sortie de SET STATISTICS IO n'est pas disponible jusqu'à la fin d'un jeu de résultats. Pour obtenir la sortie STATISTICS IO, l'application appelle SQLGetDiagRec au moment où SQLFetch ou SQLFetchScroll retourne SQL_NO_DATA. La sortie de STATISTICS IO est retournée au format suivant :
szSqlState="01000", *pfNativeError= 3615,
szErrorMsg="[Microsoft][ SQL Server Native Client][SQL Server]
Table: testshow scan count 1, logical reads: 1,
physical reads: 0."
Utilisation des instructions DBCC
Les instructions DBCC retournent leurs données comme messages, non comme jeux de résultats. SQLExecDirect ou SQLExecute retournent SQL_SUCCESS_WITH_INFO, et l'application extrait la sortie en appelant SQLGetDiagRec jusqu'à ce que SQL_NO_DATA soit retourné.
Par exemple, l'instruction suivante retourne SQL_SUCCESS_WITH_INFO :
SQLExecDirect(hstmt, "DBCC CHECKTABLE(Authors)", SQL_NTS);
Les appels de SQLGetDiagRec retournent :
szSqlState = "01000", *pfNativeError = 2536,
szErrorMsg="[Microsoft][ SQL Server Native Client][SQL Server]
Checking authors"
szSqlState = "01000", *pfNativeError = 2579,
szErrorMsg="[Microsoft][ SQL Server Native Client][SQL Server]
The total number of data pages in this table is 1."
szSqlState = "01000", *pfNativeError = 7929,
szErrorMsg="[Microsoft][ SQL Server Native Client][SQL Server]
Table has 23 data rows."
szSqlState = "01000", *pfNativeError = 2528
szErrorMsg="[Microsoft][ SQL Server Native Client][SQL Server]
DBCC execution completed. If DBCC printed error messages,
see your System Administrator."
Utilisation des instructions PRINT et RAISERROR
Les instructions Transact-SQL PRINT et RAISERROR retournent aussi les données en appelant SQLGetDiagRec. Les instructions PRINT provoquent le retour de SQL_SUCCESS_WITH_INFO par l'exécution de l'instruction SQL et l'appel suivant de SQLGetDiagRec retourne SQLState avec une valeur égale à 01000. Une erreur RAISERROR avec une gravité égale ou inférieure à dix se comporte de la même façon que PRINT. Une erreur RAISERROR avec une gravité égale à 11 ou plus provoque le retour de SQL_ERROR par l'exécution et un appel suivant de SQLGetDiagRec retourne SQLState avec une valeur égale à 42000. Par exemple, l'instruction suivante retourne SQL_SUCCESS_WITH_INFO :
SQLExecDirect (hstmt, "PRINT 'Some message' ", SQL_NTS);
L'appel de SQLGetDiagRec retourne :
szSQLState = "01000", *pfNative Error = 0,
szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server]
Some message"
L'instruction suivante retourne SQL_SUCCESS_WITH_INFO :
SQLExecDirect (hstmt, "RAISERROR ('Sample error 1.', 10, -1)",
SQL_NTS)
L'appel de SQLGetDiagRec retourne :
szSQLState = "01000", *pfNative Error = 50000,
szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server]
Sample error 1."
L'instruction suivante retourne SQL_ERROR :
SQLExecDirect (hstmt, "RAISERROR ('Sample error 2.', 11, -1)", SQL_NTS)
L'appel de SQLGetDiagRec retourne :
szSQLState = "42000", *pfNative Error = 50000,
szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server]
Sample error 2."
L'instant d'appel de SQLGetDiagRec est essentiel quand la sortie des instructions PRINT ou RAISERROR sont incluses dans un jeu de résultats. L'appel de SQLGetDiagRec pour extraire la sortie PRINT ou RAISERROR doit être effectué immédiatement après l'instruction qui reçoit SQL_ERROR ou SQL_SUCCESS_WITH_INFO. Cela est simple lorsqu'une seule instruction SQL est exécutée, comme dans les exemples ci-dessus. Dans ces cas-là, l'appel de SQLExecDirect ou SQLExecute retourne SQL_ERROR ou SQL_SUCCESS_WITH_INFO, et SQLGetDiagRec peut être appelé. La situation est moins simple lors du codage de boucles pour gérer la sortie d'un lot d'instructions SQL ou lors de l'exécution de procédures stockées SQL Server.
Dans ce cas, SQL Server retourne un jeu de résultats pour chaque instruction SELECT exécutée dans un lot ou une procédure stockée. Si le lot ou la procédure contient les instructions PRINT ou RAISERROR, leur sortie est entrelacée avec les jeux de résultats des instructions SELECT. Si la première instruction du lot ou de la procédure est PRINT ou RAISERROR, SQLExecute ou SQLExecDirect retourne SQL_SUCCESS_WITH_INFO ou SQL_ERROR, et l'application doit appeler SQLGetDiagRec jusqu'à ce qu'il retourne SQL_NO_DATA pour extraire les informations PRINT ou RAISERROR.
Si l'instruction PRINT ou RAISERROR vient après une instruction SQL (telle qu'une instruction SELECT), les informations PRINT ou RAISERROR sont retournées lorsque SQLMoreResults se positionne sur le jeu de résultats qui contient l'erreur. SQLMoreResults retourne SQL_SUCCESS_WITH_INFO ou SQL_ERROR selon la gravité du message. Les messages sont extraits en appelant SQLGetDiagRec jusqu'à ce qu'il retourne SQL_NO_DATA.