Procesar instrucciones que generan mensajes
Las opciones STATISTICS TIME y STATISTICS IO de la instrucción SET de Transact-SQL se utilizan para obtener información que ayuda a diagnosticar las consultas de ejecución prolongada. Las versiones anteriores de SQL Server también admiten la opción SHOWPLAN para analizar los planes de consulta. Una aplicación ODBC puede establecer estas opciones ejecutando las instrucciones siguientes:
SQLExecDirect(hstmt, "SET SHOWPLAN ON", SQL_NTS);
SQLExecDirect(hstmt, "SET STATISTICS TIME ON", SQL_NTS90
);
SQLExecDirect(hstmt, "SET STATISTICS IO ON", SQL_NTS);
Cuando SET STATISTICS TIME o SET SHOWPLAN son ON, SQLExecute y SQLExecDirect devuelven SQL_SUCCESS_WITH_INFO y, en ese punto, la aplicación puede recuperar la salida de SHOWPLAN o STATISTICS TIME llamando a SQLGetDiagRec hasta que devuelve SQL_NO_DATA. Cada línea de datos de SHOWPLAN se devuelve en el formato:
szSqlState="01000", *pfNativeError=6223,
szErrorMsg="[Microsoft][SQL Server Native Client][SQL Server]
Table Scan"
SQL Server versión 7.0 reemplazó la opción SHOWPLAN por SHOWPLAN_ALL y SHOWPLAN_TEXT, las dos devuelven la salida como un conjunto de resultados, no como un conjunto de mensajes.
Cada línea de STATISTICS TIME se devuelve en el formato:
szSqlState="01000", *pfNativeError= 3613,
szErrorMsg="[Microsoft][SQL Server Native Client][SQL Server]
SQL Server Parse and Compile Time: cpu time = 0 ms."
La salida de SET STATISTICS IO no está disponible hasta el final de un conjunto de resultados. Para obtener la salida de STATISTICS IO, la aplicación llama a SQLGetDiagRec en el momento en que SQLFetch o SQLFetchScroll devuelve SQL_NO_DATA. La salida de STATISTICS IO se devuelve en el formato:
szSqlState="01000", *pfNativeError= 3615,
szErrorMsg="[Microsoft][ SQL Server Native Client][SQL Server]
Table: testshow scan count 1, logical reads: 1,
physical reads: 0."
Utilizar instrucciones DBCC
Las instrucciones DBCC devuelven los datos como mensajes, no como conjuntos de resultados. SQLExecDirect o SQLExecute devuelven SQL_SUCCESS_WITH_INFO y la aplicación recupera la salida llamando a SQLGetDiagRec hasta que devuelve SQL_NO_DATA.
Por ejemplo, la instrucción siguiente devuelve SQL_SUCCESS_WITH_INFO:
SQLExecDirect(hstmt, "DBCC CHECKTABLE(Authors)", SQL_NTS);
Las llamadas a SQLGetDiagRec devuelven:
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."
Utilizar instrucciones RAISERROR y PRINT
Las instrucciones RAISERROR y PRINT de Transact-SQL también devuelven datos llamando a SQLGetDiagRec. Las instrucciones PRINT hacen que la ejecución de la instrucción SQL devuelva SQL_SUCCESS_WITH_INFO y una llamada subsiguiente a SQLGetDiagRec devuelve un SQLState de 01000. Un RAISERROR con una gravedad de diez o inferior se comporta igual que PRINT. Un RAISERROR con una gravedad de 11 o superior hace que la ejecución devuelva SQL_ERROR y una llamada subsiguiente a SQLGetDiagRec devuelve SQLState 42000. Por ejemplo, la instrucción siguiente devuelve SQL_SUCCESS_WITH_INFO:
SQLExecDirect (hstmt, "PRINT 'Some message' ", SQL_NTS);
Una llamada a SQLGetDiagRec devuelve:
szSQLState = "01000", *pfNative Error = 0,
szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server]
Some message"
La instrucción siguiente devuelve SQL_SUCCESS_WITH_INFO:
SQLExecDirect (hstmt, "RAISERROR ('Sample error 1.', 10, -1)",
SQL_NTS)
Una llamada a SQLGetDiagRec devuelve:
szSQLState = "01000", *pfNative Error = 50000,
szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server]
Sample error 1."
La siguiente instrucción devuelve SQL_ERROR.
SQLExecDirect (hstmt, "RAISERROR ('Sample error 2.', 11, -1)", SQL_NTS)
Una llamada a SQLGetDiagRec devuelve:
szSQLState = "42000", *pfNative Error = 50000,
szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server]
Sample error 2."
El control de tiempo de las llamadas a SQLGetDiagRec es crítico cuando la salida de las instrucciones PRINT o RAISERROR se incluye en un conjunto de resultados. La llamada a SQLGetDiagRec para recuperar la salida de PRINT o RAISERROR se debe realizar inmediatamente después de la instrucción que recibe SQL_ERROR o SQL_SUCCESS_WITH_INFO. Esto es sencillo cuando sólo se ejecuta una instrucción SQL única, como en los ejemplos anteriores. En estos casos, la llamada a SQLExecDirect o SQLExecute devuelve SQL_ERROR o SQL_SUCCESS_WITH_INFO y se puede llamar después a SQLGetDiagRec. Es menos sencillo al codificar los bucles para administrar la salida de un lote de instrucciones SQL o al ejecutar los procedimientos almacenados de SQL Server.
En este caso, SQL Server devuelve un conjunto de resultados para cada instrucción SELECT ejecutada en un lote o procedimiento almacenado. Si el lote o procedimiento contiene instrucciones RAISERROR o PRINT, la salida de éstas se intercala con los conjuntos de resultados de la instrucción SELECT. Si la primera instrucción del lote o procedimiento es PRINT o RAISERROR, SQLExecute o SQLExecDirect devuelve SQL_SUCCESS_WITH_INFO o SQL_ERROR y la aplicación tiene que llamar a SQLGetDiagRec hasta que devuelve SQL_NO_DATA para recuperar la información de PRINT o RAISERROR.
Si la instrucción PRINT o RAISERROR viene después de una instrucción SQL (como una instrucción SELECT), la información de PRINT o RAISERROR se devuelve cuando SQLMoreResults se coloca en el conjunto de resultados que contiene el error. SQLMoreResults devuelve SQL_SUCCESS_WITH_INFO o SQL_ERROR en función de la gravedad del mensaje. Los mensajes se recuperan llamando a SQLGetDiagRec hasta que devuelve SQL_NO_DATA.