Создание профилей данных производительности драйвера ODBC — ведение журналов длительных запросов
Применимо: SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure azure Synapse Analytics Analytics Platform System (PDW)
В этом примере показаны параметры драйвера ODBC ДЛЯ SQL Server для журналов длительных запросов. При запуске этот образец создает файл журнала Odbcqry.log, содержащий список запросов, время выполнения которых превысило интервал, установленный приложением. Этот образец не поддерживается на архитектуре IA64. Этот образец разработан для ODBC версии 3.0 или более поздней.
Внимание
По возможности используйте аутентификацию Windows. Если проверка подлинности Windows недоступна, запросите у пользователя ввод учетных данных во время выполнения. Избегайте хранения учетных данных в файле. Если необходимо сохранить учетные данные, зашифруйте их с помощью API-интерфейса шифрования Win32.
Ведение журнала длительно выполняющихся запросов с помощью администратора ODBC
В панель управления дважды щелкните "Администрирование" и дважды щелкните источники данных (ODBC). (Можно также запустить файл odbcad32.exe из командной строки.)
Перейдите на вкладку "Доменная запись пользователя", "Системная dsN" или "Файл dsN".
Щелкните источник данных, для которого создается журнал длительно выполняющихся запросов.
Нажмите Настроить.
В мастере настройки DSN Microsoft SQL Server перейдите на страницу с помощью команды "Сохранить длительные запросы" в файл журнала.
Выберите "Сохранить длительные запросы" в файл журнала. В текстовое поле введите имя файла журнала для запросов длительного выполнения. При необходимости нажмите кнопку "Обзор ", чтобы просмотреть файловую систему для журнала запросов.
Задайте интервал времени ожидания запроса в миллисекундах в поле "Долгое время запроса" (миллисекундах).
Ведение журнала длительно выполняющихся запросов программным образом
Вызовите SQLSetConnectAttr с SQL_COPT_SS_PERF_QUERY_LOG и полным путем и именем файла длительного файла журнала запросов. Например:
C:\\Odbcqry.log
Вызовите SQLSetConnectAttr с SQL_COPT_SS_PERF_QUERY_INTERVAL и задайте интервал времени ожидания в миллисекундах.
Вызовите SQLSetConnectAttr с SQL_COPT_SS_PERF_QUERY и SQL_PERF_START, чтобы начать ведение журнала длительных запросов.
Вызовите 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)