Ведение журналов длительных запросов (ODBC)

В этом образце демонстрируются параметры ODBC SQL Server, относящиеся к драйверу, для долго выполняемых запросов. При запуске этот образец создает файл журнала Odbcqry.log, содержащий список запросов, время выполнения которых превысило интервал, установленный приложением. Этот образец не поддерживается на архитектуре IA64. Этот образец разработан для ODBC версии 3.0 или более поздней.

Примечание по безопасностиПримечание по безопасности

По возможности используйте проверку подлинности Windows. Если проверка подлинности Windows недоступна, запросите у пользователя ввод учетных данных во время выполнения. Избегайте хранения учетных данных в файле. Если необходимо сохранить учетные данные, зашифруйте их с помощью API-интерфейса шифрования Win32.

Ведение журнала длительно выполняющихся запросов с помощью администратора ODBC

  1. На панели управления дважды щелкните пункт Администрирование, а затем Источники данных (ODBC). (Можно также запустить файл odbcad32.exe из командной строки.)

  2. Откройте вкладку Пользовательский DSN, Системный DSN или Файловый DSN.

  3. Щелкните источник данных, для которого создается журнал длительно выполняющихся запросов.

  4. Нажмите кнопку Настройка.

  5. В мастере настройки DSN сервера Microsoft SQL Server перейдите на страницу Сохранение длительных запросов в файл журнала.

  6. Выберите Сохранять длительные запросы в журнал. В текстовое поле введите имя файла журнала для запросов длительного выполнения. Можно нажать кнопку Обзор, чтобы выбрать файл журнала в файловой системе.

  7. В поле Длительность запроса (мс) введите длительность времени ожидания (в миллисекундах).

Ведение журнала длительно выполняющихся запросов программным образом

  1. Вызовите SQLSetConnectAttr со следующими параметрами: SQL_COPT_SS_PERF_QUERY_LOG, полный путь и имя файла журнала длительно выполняющихся запросов. Например:

    C:\\Odbcqry.log
    
  2. Вызовите метод SQLSetConnectAttr с параметром SQL_COPT_SS_PERF_QUERY_INTERVAL и задайте время ожидания в миллисекундах.

  3. Чтобы начать запись в журнал длительно выполняющихся запросов, вызовите функцию SQLSetConnectAttr с параметрами SQL_COPT_SS_PERF_QUERY и SQL_PERF_START.

  4. Чтобы прекратить запись в журнал длительно выполняющихся запросов, вызовите функцию SQLSetConnectAttr с параметрами SQL_COPT_SS_PERF_QUERY и SQL_PERF_STOP.

Пример

Также необходим источник данных ODBC с именем AdventureWorks, для которого базой данных по умолчанию является образец базы данных AdventureWorks. (Образец базы данных AdventureWorks можно загрузить с домашней страницы Образцы кода и проекты сообщества Microsoft SQL Server (возможно, на английском языке).) Этот источник данных должен быть основан на драйвере ODBC, предоставленном операционной системой (имя драйвера — «SQL Server»). При построении и запуске этого образца как 32-разрядного приложения в 64-разрядной операционной системе необходимо создать источник данных ODBC с помощью программы администрирования ODBC (исполняемый файл %windir%\SysWOW64\odbcad32.exe).

Этот образец соединяется с установленным на компьютер экземпляром SQL Server по умолчанию. Чтобы соединиться с именованным экземпляром, измените определение источника данных ODBC, чтобы указать экземпляр с помощью следующего формата: сервер\именованный_экземпляр. По умолчанию SQL Server Express устанавливается на именованный экземпляр.

Скомпилируйте с библиотекой 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);
}

См. также

Другие ресурсы

Инструкции по измерению производительности драйвера ODBC (ODBC)