Perfilagem de Dados de Desempenho do Driver ODBC - Registo de Consultas de Longa Duração

Aplica-se a:SQL ServerBase de Dados SQL do AzureInstância Gerida do Azure SQLAzure Synapse Analytics

Este exemplo mostra as opções específicas do SQL Server ODBC para registar consultas de longa duração. Quando executado, este exemplo cria Odbcqry.log, que contém uma lista de consultas cuja execução excede um intervalo definido pela aplicação. Este exemplo não é suportado no IA64. Este exemplo foi desenvolvido para a versão 3.0 do ODBC ou posterior.

Importante

Quando possível, use a Autenticação do Windows. Se a Autenticação Windows não estiver disponível, peça aos utilizadores para introduzirem as suas credenciais em tempo de execução. Evite guardar credenciais num ficheiro. Se tiver de manter credenciais, deve encriptá-las com a API criptográfica Win32.

Para registar consultas de longa duração usando o ODBC Administrator

  1. No Painel de Controlo, clique duas vezes em Ferramentas Administrativas e depois em Fontes de Dados (ODBC). (Alternativamente, pode correr odbcad32.exe a partir do prompt de comandos.)

  2. Clique no separador DSN do Utilizador, DSN do Sistema ou DSN do Ficheiro .

  3. Clique na fonte de dados para registar consultas de longa duração.

  4. Clique em Configurar.

  5. No Microsoft SQL Server Configure DSN Wizard, navegue até à página com Guardar consultas de longa duração no ficheiro de log.

  6. Selecione Guardar consultas de longa duração no ficheiro de registo. Na caixa, coloque o nome do ficheiro onde as consultas de longa duração devem ser registadas. Opcionalmente, clique em Navegar para navegar pelo sistema de ficheiros do registo de consultas.

  7. Defina um intervalo de tempo de espera da consulta, em milissegundos, na caixa de tempo de consulta longo (milissegundos).

Para registar dados de consultas de longa duração programaticamente

  1. Chame SQLSetConnectAttr com SQL_COPT_SS_PERF_QUERY_LOG e o caminho completo e o nome do ficheiro de registo de consultas de longa duração. Por exemplo:

    C:\\Odbcqry.log  
    
  2. Chame SQLSetConnectAttr com SQL_COPT_SS_PERF_QUERY_INTERVAL e defina para o intervalo de time-out, em milissegundos.

  3. Ligue para SQLSetConnectAttr com SQL_COPT_SS_PERF_QUERY e SQL_PERF_START para começar a registar consultas de longa duração.

  4. Ligue para SQLSetConnectAttr com SQL_COPT_SS_PERF_QUERY e SQL_PERF_STOP para deixar de registar consultas prolongadas.

Example

Vai precisar de uma fonte de dados ODBC chamada AdventureWorks, cuja base de dados padrão é a base de dados de exemplos AdventureWorks. (Pode descarregar a base de dados de exemplos AdventureWorks a partir do repositório GitHub do Azure Data SQL Samples Repository.) Esta fonte de dados deve basear-se no driver ODBC fornecido pelo sistema operativo (o nome do driver é "SQL Server"). Se for construir e executar este exemplo como uma aplicação de 32 bits num sistema operativo de 64 bits, deve criar a fonte de dados ODBC com o ODBC Administrator em %windir%\SysWOW64\odbcad32.exe.

Este exemplo liga-se à instância padrão do SQL Server do seu computador. Para se ligar a uma instância nomeada, altere a definição da fonte de dados ODBC para especificar a instância usando o seguinte formato: server\namedinstance. Por defeito, o SQL Server Express instala-se numa instância nomeada.

Compilar com odbc32.lib.

// compile with: odbc32.lib  
#include <stdio.h>  
#include <string.h>  
#include <windows.h>  
#include <sql.h>  
#include <sqlext.h>  
#include <odbcss.h>  
  
SQLHENV henv = SQL_NULL_HENV;  
SQLHDBC hdbc1 = SQL_NULL_HDBC;       
SQLHSTMT hstmt1 = SQL_NULL_HSTMT;  
  
void Cleanup() {  
   if (hstmt1 != SQL_NULL_HSTMT)  
      SQLFreeHandle(SQL_HANDLE_STMT, hstmt1);  
  
   if (hdbc1 != SQL_NULL_HDBC) {  
      SQLDisconnect(hdbc1);  
      SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);  
   }  
  
   if (henv != SQL_NULL_HENV)  
      SQLFreeHandle(SQL_HANDLE_ENV, henv);  
}  
  
int main() {  
   RETCODE retcode;  
  
   // Allocate the ODBC environment and save handle.  
   retcode = SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv);  
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {  
      printf("SQLAllocHandle(Env) Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Notify ODBC that this is an ODBC 3.0 app.  
   retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);  
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {  
      printf("SQLSetEnvAttr(ODBC version) Failed\n\n");  
      Cleanup();  
      return(9);      
   }  
  
   // Allocate ODBC connection handle and connect.  
   retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1);  
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {  
      printf("SQLAllocHandle(hdbc1) Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // sample uses Integrated Security, create SQL Server DSN using the Windows NT authentication.   
   retcode = SQLConnect(hdbc1, (UCHAR*)"AdventureWorks", SQL_NTS, (UCHAR*)"",SQL_NTS, (UCHAR*)"", SQL_NTS);  
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLConnect() Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Set options to log long-running queries, including the file to use for the log.  
   retcode = SQLSetConnectAttr( hdbc1, SQL_COPT_SS_PERF_QUERY_LOG, &"odbcqry.log", SQL_NTS);  
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLSetConnectAttr Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Set the long-running query interval (in milliseconds).  Note that for version 2.50 and 2.65  
   // drivers, this value is specified in seconds, not milliseconds.  
   retcode =   
      SQLSetConnectAttr( hdbc1, SQL_COPT_SS_PERF_QUERY_INTERVAL, (SQLPOINTER)3000, SQL_IS_UINTEGER);  
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLSetConnectAttr Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Start the long-running query log.  
   retcode =   
      SQLSetConnectAttr( hdbc1, SQL_COPT_SS_PERF_QUERY, (SQLPOINTER)SQL_PERF_START, SQL_IS_UINTEGER);  
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLSetConnectAttr Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Allocate statement handle then execute commands.  
   retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc1, &hstmt1);  
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLAllocHandle(hstmt1) Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   retcode = SQLExecDirect(hstmt1, (UCHAR*)"SELECT * FROM Purchasing.Vendor", SQL_NTS);  
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLExecDirect Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Clear any result sets generated.  
   while ( ( retcode = SQLMoreResults(hstmt1) ) != SQL_NO_DATA ) {  
      if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
         printf("SQLMoreResults Failed\n\n");  
         Cleanup();  
           return(9);  
      }  
   }  
  
   retcode = SQLExecDirect(hstmt1, (UCHAR*)"SELECT * FROM Sales.Store", SQL_NTS);  
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLExecDirect Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Clear any result sets generated.  
   while ( ( retcode = SQLMoreResults(hstmt1) ) != SQL_NO_DATA ) {  
      if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
         printf("SQLMoreResults Failed\n\n");  
         Cleanup();  
         return(9);  
      }  
   }  
  
   // Generate a long-running query.  
   retcode = SQLExecDirect(hstmt1, (UCHAR*)"waitfor delay '00:00:04' ", SQL_NTS);  
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLExecDirect Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Clear any result sets generated.  
   while ( ( retcode = SQLMoreResults(hstmt1) ) != SQL_NO_DATA ) {  
      if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
         printf("SQLMoreResults Failed\n\n");  
         Cleanup();  
         return(9);  
      }  
   }  
  
   // Cleanup  
   SQLFreeHandle(SQL_HANDLE_STMT, hstmt1);  
   SQLDisconnect(hdbc1);  
   SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);  
   SQLFreeHandle(SQL_HANDLE_ENV, henv);  
}