Поделиться через


Набор записей. Объявление класса для предопределенного запроса (ODBC)

Примечание.

Мастер потребителя MFC ODBC недоступен в Visual Studio 2019 и более поздних версиях. При этом вы по-прежнему можете создать потребитель вручную.

Этот раздел относится к классам ODBC библиотеки MFC.

В этом разделе описывается создание класса набора записей класса для предопределенного запроса (иногда называется хранимой процедурой, как в Microsoft SQL Server).

Примечание.

Этот раздел относится к объектам, производным от CRecordset, в которых пакетное получение строк не реализовано. Если реализовано пакетное получение строк, процесс очень похож. Сведения о различиях между наборами записей, реализующими массовое получение строк и не имеющихся, см. в разделе Recordseting Records: Fetching Records in Bulk (ODBC).

Некоторые системы управления базами данных (СУБД) позволяют создавать предопределенный запрос и вызывать его из программ, как функцию. У запроса есть имя, он может принимать параметры и возвращать записи. Процедура в этом разделе описывает, как вызвать предопределенный запрос, который возвращает записи (и, возможно, принимает параметры).

Классы баз данных не поддерживают обновление предопределенных запросов. Разница между предопределенным запросом моментальных снимков и предопределенным запросом динамического подмножества не в обновляемости, а в том, видимы ли изменения, внесенные другими пользователями (или другими наборами записей в программе) в вашем наборе записей.

Совет

Вам не нужен набор записей для вызова предопределенного запроса, который не возвращает записи. Подготовьте инструкцию SQL, как описано ниже, но выполните ее, вызвав функцию элемента CDatabaseExecuteSQL.

Вы можете создать один класс набора записей для управления вызовом предопределенного запроса, но вы должны проделать некоторую работу самостоятельно. Мастера не поддерживают создание класса специально для этой цели.

Создание класса для вызова предопределенного запроса (хранимая процедура)

  1. Используйте мастер объекта-получателя MFC ODBC из Добавление класса, чтобы создать класс набора записей для таблицы, содержащей большинство столбцов, возвращаемых запросом. Это дает вам преимущество.

  2. Вручную добавьте элементы данных полей для всех столбцов всех таблиц, возвращаемых запросом, но не созданных мастером.

    Например, если запрос возвращает три столбца из двух дополнительных таблиц, добавьте к классу шесть элементов данных полей (соответствующих типов данных).

  3. Вручную добавьте вызовы функции RFX в функцию элемента DoFieldExchange класса в соответствии с типом данных каждого добавленного элемента данных полей.

    Immediately before these RFX calls, call <MSHelp:link keywords="_mfc_CFieldExchange.3a3a.SetFieldType" TABINDEX="0">SetFieldType</MSHelp:link>, as shown here:
    pFX->SetFieldType( CFieldExchange::outputColumn );
    

    Примечание.

    Необходимо знать типы данных и порядок столбцов, возвращаемых в результирующем наборе. Порядок вызовов функций RFX в DoFieldExchange должен соответствовать порядку столбцов результирующего набора.

  4. Вручную добавьте инициализации для новых элементов данных полей в конструкторе класса набора записей.

    Кроме того, необходимо увеличить значение инициализации для элемента данных m_nFields. Мастер пишет инициализацию, но она охватывает только элементы данных полей, которые он добавил сам. Например:

    m_nFields += 6;
    

    Некоторые типы данных не должны инициализироваться здесь, например CLongBinary или массивы байтов.

  5. Если запрос принимает параметры, добавьте элемент данных параметра для каждого параметра, вызов функции RFX для каждого параметра и инициализацию для каждого параметра.

  6. Необходимо увеличить m_nParams для каждого добавленного параметра, как вы делали это для m_nFields для добавленных полей на шаге 4 этой процедуры. Дополнительные сведения см. в разделе Recordset: параметризация набора записей (ODBC).

  7. Вручную напишите строку инструкции SQL по следующей форме:

    {CALL proc-name [(? [, ?]...)]}
    

    где CALL — это ключевое слово ODBC, proc-name — это имя запроса, известного в источнике данных, а элементы "?" — это местозаполнители для значений параметров, которые вы передаете в набор записей во время выполнения (если таковые имеются). В следующем примере подготавливается заполнитель для одного параметра:

    CString mySQL = "{CALL Delinquent_Accts (?)}";
    
  8. В коде, который открывает набор записей, задайте значения элементов данных параметров набора записей, а затем вызовите функцию элемента Open, передав строку SQL для параметра lpszSQL. Либо замените строку, возвращаемую функцией элемента GetDefaultSQL в классе.

В следующих примерах показана процедура вызова предопределенного запроса с именем Delinquent_Accts, который принимает один параметр — номер региона продаж. Этот запрос возвращает три столбца: Acct_No, L_Name, Phone. Все столбцы взяты из таблицы Customers.

Следующий набор записей определяет элементы данных полей для столбцов, возвращаемых запросом, и параметр номера региона продаж, запрошенный в среде выполнения.

class CDelinquents : public CRecordset
{
// Field/Param Data
    LONG m_lAcct_No;
    CString m_strL_Name;
    CString m_strPhone;
    LONG m_lDistParam;
    // ...
};

Это объявление класса написано мастером, а элемент m_lDistParam добавлен вручную. Другие элементы здесь не показаны.

В следующем примере показаны инициализации для элементов данных в конструкторе CDelinquents.

CDelinquents::CDelinquents(CDatabase* pdb)
   : CRecordset(pdb)
{
    // Wizard-generated params:
    m_lAcct_No = 0;
    m_strL_Name = "";
    m_strPhone = "";
    m_nFields = 3;
    // User-defined params:
    m_nParams = 1;
    m_lDistParam = 0;
}

Обратите внимание на инициализации для m_nFields и m_nParams. Мастер инициализирует m_nFields; вы инициализируете m_nParams.

В следующем примере показаны функции RFX в CDelinquents::DoFieldExchange:

void CDelinquents::DoFieldExchange(CFieldExchange* pFX)
{
    pFX->SetFieldType(CFieldExchange::outputColumn);
    RFX_Long(pFX, "Acct_No", m_lAcct_No);
    RFX_Text(pFX, "L_Name", m_strL_Name);
    RFX_Text(pFX, "Phone", m_strPhone);
    pFX->SetFieldType(CFieldExchange::param);
    RFX_Long(pFX, "Dist_No", m_lDistParam);
}

Помимо вызовов RFX для трех возвращаемых столбцов, этот код также управляет привязкой параметра, который вы передаете в среде выполнения. Параметр подключается к столбцу Dist_No (номер региона).

В следующем примере показано, как настроить строку SQL и использовать ее, чтобы открыть набор записей.

// Construct a CDelinquents recordset object
CDelinquents rsDel( NULL );
CString strSQL = "{CALL Delinquent_Accts (?)}"
// Specify a parameter value (obtained earlier from the user)
rsDel.m_lDistParam = lDistrict;
// Open the recordset and run the query
if( rsDel.Open( CRecordset::snapshot, strSQL ) )
    // Use the recordset ...

Этот код создает моментальный снимок, передает ему параметр, полученный ранее от пользователя, и вызывает предопределенный запрос. При выполнении запроса возвращаются записи для указанного региона продаж. Каждая запись содержит столбцы для номера счета, фамилии клиента и номера телефона клиента.

Совет

Возможно, вам потребуется обработать возвращаемое значение (выходной параметр) из хранимой процедуры. Дополнительные сведения и пример см. в разделе CFieldExchange::SetFieldType.

См. также

Набор записей (ODBC)
Набор записей. Выполнение обновления наборов записей (ODBC)
Набор записей. Объявление класса таблицы (ODBC)
Набор записей. Объединение (ODBC)