SQL. Настройка инструкции SQL набора записей (ODBC)

Содержание раздела:

  • Процесс создания платформой инструкции SQL

  • Процесс переопределения инструкции SQL

ПримечаниеПримечание

В этом разделе приведены сведения, относящиеся к классам ODBC библиотеки MFC.Сведения, относящиеся к классам DAO библиотеки MFC, см. в разделе "Сравнение ядра СУБД Microsoft Jet SQL и ANSI SQL" в справке DAO.

Создание инструкции SQL

Выбор записей для набора записей главным образом основан на инструкции SQL SELECT.При объявлении класса с помощью мастера он создает переопределение функции-члена GetDefaultSQL, которое выглядит примерно следующим образом (для класса набора записей с именем CAuthors).

CString CAuthors::GetDefaultSQL()
{
    return "AUTHORS";
}

По умолчанию в результате переопределения возвращается название таблицы, указанное в мастере.В этом примере в качестве названия таблицы используется "AUTHORS". При последующем вызове функции-члена набора записей Open функция Open создает окончательную инструкцию SELECT для формы:

SELECT rfx-field-list FROM table-name [WHERE m_strFilter] 
       [ORDER BY m_strSort]

Здесь имя table-name получено в результате вызова GetDefaultSQL, а список rfx-field-list формируется путем вызова функций RFX в функции DoFieldExchange.Инструкция SELECT будет иметь именно такой вид, если только она не будет заменена переопределением во время выполнения, хотя инструкцию по умолчанию также можно изменить с помощью параметров или фильтра.

ПримечаниеПримечание

При указании имени столбца, который содержит (или может содержать) пробелы, его необходимо заключать в квадратные скобки.Например, имя "Имя автора" должно иметь вид "[Имя автора]".

Чтобы переопределить используемую по умолчанию инструкцию SELECT, при вызове функции Open следует передать строку с полноценной инструкцией SELECT.Вместо создания собственной строки по умолчанию набор записей будет использовать указанную строку.Если замещающая инструкция содержит предложение WHERE, то указывать фильтр в элементе m_strFilter не следует, иначе будет получено две инструкции фильтрации.Аналогично, если замещающая инструкция содержит предложение ORDER BY, то не следует задавать сортировку в m_strSort, иначе это приведет к созданию двух инструкций сортировки.

ПримечаниеПримечание

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

В зависимости от используемой СУБД также могут встречаться особые требования к синтаксису для инструкций — например, для внешнего соединения.Для получения соответствующей информации от драйвера СУБД можно использовать функции ODBC.Так, например, можно вызвать функцию ::SQLGetTypeInfo для определенного типа данных, например SQL_VARCHAR, чтобы запросить знаки LITERAL_PREFIX и LITERAL_SUFFIX.При создании кода, не зависящего от базы данных, подробные сведения по синтаксису см. в приложении В к Справочнику программистапакета SDK ODBC на компакт-диске библиотеки MSDN.

Объект набора записей создает инструкцию SQL, используемую для выбора записей, если не была задана пользовательская инструкция SQL.Способ передачи главным образом зависит от значения, передаваемого в параметре lpszSQL функции-члена Open.

Созданная инструкция SQL SELECT выглядит следующим образом:

SELECT [ALL | DISTINCT] column-list FROM table-list
    [WHERE search-condition][ORDER BY column-list [ASC | DESC]]

Одним из способов добавления ключевого слова DISTINCT к инструкции SQL набора записей является внедрение этого ключевого слова в первый вызов функции RFX в DoFieldExchange.Например:

...
    RFX_Text(pFX, "DISTINCT CourseID", m_strCourseID);
...
ПримечаниеПримечание

Этот способ следует использовать только для наборов данных, открываемых в режиме "только для чтения".

Переопределение инструкции SQL

В следующей таблице перечислены возможности параметра lpszSQL функции Open.Приведенные в таблице случаи поясняются ниже.

Параметр lpszSQL и результирующая строка SQL

Case

Элементы, передаваемые в lpszSQL

Результирующая инструкция SELECT

1

NULL

SELECTrfx-field-listFROMtable-name

Для получения имени таблицы функция CRecordset::Open вызывает функцию GetDefaultSQL.Результирующая строка будет соответствовать одному из случаев 2–5, в зависимости от того, что возвращает функция GetDefaultSQL.

2

Имя таблицы

SELECTrfx-field-listFROMtable-name

Список полей извлекается из инструкций RFX в DoFieldExchange.Если поля m_strFilter и m_strSort не пусты, добавляются предложения WHERE и/или ORDER BY.

3 *

Полная инструкция SELECT без предложений WHERE или ORDER BY

В соответствии с переданным значением.Если поля m_strFilter и m_strSort не пусты, добавляются предложения WHERE и/или ORDER BY.

4 *

Полная инструкция SELECT с предложениями WHERE и/или ORDER BY

В соответствии с переданным значением.Поля m_strFilter и m_strSort должны быть пустыми, или же будет создано две инструкции фильтрации или сортировки.

5 *

Вызов хранимой процедуры

В соответствии с переданным значением.

* Значение m_nFields должно быть меньше или равно количеству столбцов, указанных в инструкции SELECT.Тип данных каждого столбца, указанного в инструкции SELECT, должен совпадать с типом данных соответствующего выходного столбца RFX.

6hs301kk.collapse_all(ru-ru,VS.110).gifСлучай 1 lpszSQL = NULL

Выборка набора записей зависит от того, что возвращает функция GetDefaultSQL при вызове из функции CRecordset::Open.В случаях 2-5 описываются возможные строки.

6hs301kk.collapse_all(ru-ru,VS.110).gifСлучай 2 lpszSQL = имя таблицы

Набор записей использует обмен полей записей (RFX) для создания списка столбцов по именам столбцов, полученных в результате вызова функций RFX в переопределенной функции-члене DoFieldExchange класса набора записей.Если для объявления класса набора записей использовался мастер, результат в этом случае будет совпадать с результатом в случае 1 (при условии, что переданное имя таблицы соответствует имени, указанному в мастере).Если для создания класса мастер не использовался, наиболее простым способом создания инструкции SQL является случай 2.

В следующем примере показано создание инструкции SQL, которая выбирает записи из базы данных в приложении MFC.При вызове платформой функции-члена GetDefaultSQL функция возвращает имя таблицы — SECTION.

CString CEnrollSet::GetDefaultSQL()
{
    return "SECTION";
}

Чтобы получить имена столбцов для инструкции SQL SELECT, платформа вызывает функцию-член DoFieldExchange.

void CEnrollSet::DoFieldExchange(CFieldExchange* pFX)
{
    pFX->SetFieldType(CFieldExchange::outputColumn);
    RFX_Text(pFX, "CourseID", m_strCourseID);
    RFX_Text(pFX, "InstructorID", m_strInstructorID);
    RFX_Text(pFX, "RoomNo", m_strRoomNo);
    RFX_Text(pFX, "Schedule", m_strSchedule);
    RFX_Text(pFX, "SectionNo", m_strSectionNo);
}

После завершения инструкция SQL выглядит следующим образом:

SELECT CourseID, InstructorID, RoomNo, Schedule, SectionNo 
    FROM SECTION

6hs301kk.collapse_all(ru-ru,VS.110).gifCase 3 lpszSQL = SELECT/FROM выписка

Вместо автоматического создания с помощью RFX список столбцов задается вручную.Такой способ может быть предпочтительным в следующих случаях:

  • Если после инструкции SELECT необходимо указать ключевое слово DISTINCT.

    Список столбцов должен соответствовать именам, типам и порядку перечисления столбцов в DoFieldExchange.

  • Если необходимо вручную извлечь значения столбцов с помощью функции ODBC ::SQLGetData вместо того, чтобы использовать RFX для автоматического связывания и извлечения столбцов.

    Например, может быть необходимо включить новые столбцы, которые пользователь приложения добавил в базу данных после распространения приложения.Соответственно, необходимо добавить новые члены-поля данных, которые не были известны во время объявления класса с помощью мастера.

    Список столбцов должен соответствовать именам, типам и порядку перечисления столбцов DoFieldExchange, после которых должны следовать имена столбцов, связываемых вручную.Дополнительные сведения см. в разделе Набор записей. Динамическая привязка столбцов данных (ODBC).

  • Если в предложении FROM необходимо выполнить соединение таблиц.

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

6hs301kk.collapse_all(ru-ru,VS.110).gifСлучай 4 lpszSQL = SELECT/FROM плюс WHERE и/или ORDER BY

Указывается все: список столбцов (основанный на вызовах RFX в DoFieldExchange), список таблиц и содержимое предложений WHERE и/или ORDER BY.При указании предложений WHERE и/или ORDER BY подобным образом нельзя использовать поля m_strFilter и/или m_strSort.

6hs301kk.collapse_all(ru-ru,VS.110).gifСлучай 5 lpszSQL = вызов хранимой процедуры

Если необходимо вызвать предопределенный запрос (например, хранимую процедуру в базе данных Microsoft SQL Server), следует записать оператор CALL в строке, передаваемой в lpszSQL.Мастера не поддерживает объявление класса набора записей для вызова предопределенного запроса.Не все предопределенные запросы возвращают записи.

Если предопределенный запрос не возвращает записи, можно воспользоваться функцией-членом класса CDatabaseExecuteSQL напрямую.Для предопределенных запросов, возвращающих записи, необходимо вручную записать вызовы RFX в DoFieldExchange для всех столбцов, возвращаемых процедурой.Вызовы RFX должны иметь тот же порядок и возвращать те же типы, что и предопределенный запрос.Дополнительные сведения см. в разделе Набор записей. Объявление класса для предопределенного запроса (ODBC).

См. также

Основные понятия

SQL. Типы данных SQL и C++ (ODBC)

SQL. Выполнение прямых вызовов SQL (ODBC)