--- title: "Processing Statements That Generate Messages | Microsoft Docs" ms.custom: "" ms.date: "03/14/2017" ms.prod: sql ms.prod_service: "database-engine, sql-database, sql-data-warehouse, pdw" ms.reviewer: "" ms.technology: native-client ms.topic: "reference" helpviewer_keywords: - "PRINT statement" - "messages [ODBC], statements generating messages" - "statements [ODBC], message generation" - "errors [ODBC], statements generating messages" - "SQL Server Native Client ODBC driver, errors" - "STATISTICS IO option" - "STATISTICS TIME option" - "DBCC statements" - "SQLExecute function" - "RAISERROR statement" - "SQLGetDiagRec function" - "ODBC error handling, statements generating messages" - "SQLExecDirect function" ms.assetid: 672ebdc5-7fa1-4ceb-8d52-fd25ef646654 author: markingmyname ms.author: maghan monikerRange: ">=aps-pdw-2016||=azuresqldb-current||=azure-sqldw-latest||>=sql-server-2016||=sqlallproducts-allversions||>=sql-server-linux-2017||=azuresqldb-mi-current" --- # Processing Statements That Generate Messages [!INCLUDE[appliesto-ss-asdb-asdw-pdw-md](../../includes/appliesto-ss-asdb-asdw-pdw-md.md)] The [!INCLUDE[tsql](../../includes/tsql-md.md)] SET statement options STATISTICS TIME and STATISTICS IO are used to get information that aids in diagnosing long-running queries. Earlier versions of [!INCLUDE[ssNoVersion](../../includes/ssnoversion-md.md)] also support the SHOWPLAN option for analyzing query plans. An ODBC application can set these options by executing the following statements: ``` SQLExecDirect(hstmt, "SET SHOWPLAN ON", SQL_NTS); SQLExecDirect(hstmt, "SET STATISTICS TIME ON", SQL_NTS90 ); SQLExecDirect(hstmt, "SET STATISTICS IO ON", SQL_NTS); ``` When SET STATISTICS TIME or SET SHOWPLAN are ON, **SQLExecute** and **SQLExecDirect** return SQL_SUCCESS_WITH_INFO, and, at that point, the application can retrieve the SHOWPLAN or STATISTICS TIME output by calling **SQLGetDiagRec** until it returns SQL_NO_DATA. Each line of SHOWPLAN data comes back in the format: ``` szSqlState="01000", *pfNativeError=6223, szErrorMsg="[Microsoft][SQL Server Native Client][SQL Server] Table Scan" ``` [!INCLUDE[ssNoVersion](../../includes/ssnoversion-md.md)] version 7.0 replaced the SHOWPLAN option with SHOWPLAN_ALL and SHOWPLAN_TEXT, both of which return output as a result set, not a set of messages. Each line of STATISTICS TIME comes back in the format: ``` szSqlState="01000", *pfNativeError= 3613, szErrorMsg="[Microsoft][SQL Server Native Client][SQL Server] SQL Server Parse and Compile Time: cpu time = 0 ms." ``` The output of SET STATISTICS IO is not available until the end of a result set. To get STATISTICS IO output, the application calls **SQLGetDiagRec** at the time **SQLFetch** or [SQLFetchScroll](../../relational-databases/native-client-odbc-api/sqlfetchscroll.md) returns SQL_NO_DATA. The output of STATISTICS IO comes back in the format: ``` szSqlState="01000", *pfNativeError= 3615, szErrorMsg="[Microsoft][ SQL Server Native Client][SQL Server] Table: testshow scan count 1, logical reads: 1, physical reads: 0." ``` ## Using DBCC Statements DBCC statements return their data as messages, not result sets. **SQLExecDirect** or **SQLExecute** return SQL_SUCCESS_WITH_INFO, and the application retrieves the output by calling **SQLGetDiagRec** until it returns SQL_NO_DATA. For example, the following statement returns SQL_SUCCESS_WITH_INFO: ``` SQLExecDirect(hstmt, "DBCC CHECKTABLE(Authors)", SQL_NTS); ``` Calls to **SQLGetDiagRec** return: ``` 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." ``` ## Using PRINT and RAISERROR Statements [!INCLUDE[tsql](../../includes/tsql-md.md)] PRINT and RAISERROR statements also return data by calling **SQLGetDiagRec**. PRINT statements cause the SQL statement execution to return SQL_SUCCESS_WITH_INFO, and a subsequent call to **SQLGetDiagRec** returns a *SQLState* of 01000. A RAISERROR with a severity of ten or lower behaves the same as PRINT. A RAISERROR with a severity of 11 or higher causes the execute to return SQL_ERROR, and a subsequent call to **SQLGetDiagRec** returns *SQLState* 42000. For example, the following statement returns SQL_SUCCESS_WITH_INFO: ``` SQLExecDirect (hstmt, "PRINT 'Some message' ", SQL_NTS); ``` Calling **SQLGetDiagRec** returns: ``` szSQLState = "01000", *pfNative Error = 0, szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server] Some message" ``` The following statement returns SQL_SUCCESS_WITH_INFO: ``` SQLExecDirect (hstmt, "RAISERROR ('Sample error 1.', 10, -1)", SQL_NTS) ``` Calling **SQLGetDiagRec** returns: ``` szSQLState = "01000", *pfNative Error = 50000, szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server] Sample error 1." ``` The following statement returns SQL_ERROR: ``` SQLExecDirect (hstmt, "RAISERROR ('Sample error 2.', 11, -1)", SQL_NTS) ``` Calling **SQLGetDiagRec** returns: ``` szSQLState = "42000", *pfNative Error = 50000, szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server] Sample error 2." ``` The timing of calling **SQLGetDiagRec** is critical when output from PRINT or RAISERROR statements is included in a result set. The call to **SQLGetDiagRec** to retrieve the PRINT or RAISERROR output must be made immediately after the statement that receives SQL_ERROR or SQL_SUCCESS_WITH_INFO. This is straightforward when only a single SQL statement is executed, as in the examples above. In these cases, the call to **SQLExecDirect** or **SQLExecute** returns SQL_ERROR or SQL_SUCCESS_WITH_INFO and **SQLGetDiagRec** can then be called. It is less straightforward when coding loops to handle the output of a batch of SQL statements or when executing [!INCLUDE[ssNoVersion](../../includes/ssnoversion-md.md)] stored procedures. In this case, [!INCLUDE[ssNoVersion](../../includes/ssnoversion-md.md)] returns a result set for every SELECT statement executed in a batch or stored procedure. If the batch or procedure contains PRINT or RAISERROR statements, the output for these is interleaved with the SELECT statement result sets. If the first statement in the batch or procedure is a PRINT or RAISERROR, the **SQLExecute** or **SQLExecDirect** returns SQL_SUCCESS_WITH_INFO or SQL_ERROR, and the application needs to call **SQLGetDiagRec** until it returns SQL_NO_DATA to retrieve the PRINT or RAISERROR information. If the PRINT or RAISERROR statement comes after an SQL statement (such as a SELECT statement), then the PRINT or RAISERROR information is returned when [SQLMoreResults](../../relational-databases/native-client-odbc-api/sqlmoreresults.md)positions on the result set containing the error. **SQLMoreResults** returns SQL_SUCCESS_WITH_INFO or SQL_ERROR depending on the severity of the message. Messages are retrieved by calling **SQLGetDiagRec** until it returns SQL_NO_DATA. ## See Also [Handling Errors and Messages](../../relational-databases/native-client-odbc-error-messages/handling-errors-and-messages.md)