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


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

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

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

Примечание

В этом разделе приведены сведения, относящиеся к объектам, производным от класса CRecordset, в котором групповая выборка строк не реализована.Для случая, когда групповая выборка реализована, процесс практически аналогичный.Информацию о различиях между наборами записей, в которых групповая выборка строк реализована и не реализована, см. в разделе Набор записей. Групповая выборка строк (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 этой процедуры. Дополнительные сведения см. в разделе Набор записей. Параметризация набора записей (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. Все эти столбцы из таблицы "Клиенты".

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

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)