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


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";
}

По умолчанию это переопределение возвращает имя таблицы, указанное в мастере. В примере имя таблицы — "АВТОРЫ". При последующем вызове функции-члена 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 по умолчанию, передайте строку, содержащую полную инструкцию SELECT Вместо создания собственной строки по умолчанию набор записей использует заданную строку. Если инструкция замены содержит предложение WHERE , не указывайте фильтр, m_strFilter так как у вас будет два оператора фильтра. Аналогичным образом, если инструкция замены содержит предложение ORDER BY , не указывайте сортировку таким m_strSort образом, чтобы у вас не было двух операторов сортировки.

Примечание.

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

Вы также можете столкнуться со специальными синтаксическими требованиями для таких операций, как внешние соединения, в зависимости от СУБД. Используйте функции ODBC для получения этих сведений от драйвера для СУБД. Например, вызов ::SQLGetTypeInfo конкретного типа данных, например SQL_VARCHARзапрос LITERAL_PREFIX и LITERAL_SUFFIX символов. Если вы пишете независимый от базы данных код, ознакомьтесь с приложением C: Грамматика SQL в справочнике программиста ODBC для получения подробных сведений о синтаксисе.

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

Общая форма инструкции 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 и результирующая строка SQL

Регистр То, что вы передаете в lpszSQL Результирующая инструкция SELECT
1 Отсутствует 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.

Регистр 1 lpszSQL = NULL

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

Регистр 2 lpszSQL = имя таблицы

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

В следующем примере создается инструкция 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

Case 3 lpszSQL = инструкция SELECT/FROM

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

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

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

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

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

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

  • Вы хотите присоединить таблицы, указав несколько таблиц в предложении FROM .

    Сведения и пример см. в разделе Recordset: Выполнение соединения (ODBC).

Случай 4 lpszSQL = SELECT/FROM Plus WHERE и/или ORDER BY

Вы указываете все: список столбцов (на основе вызовов RFX), DoFieldExchangeтабличного списка и содержимого предложения WHERE и /или ПРЕДЛОЖЕНИЯ ORDER BY . Если вы укажете предложения WHERE

Case 5 lpszSQL = вызов хранимой процедуры

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

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

См. также

SQL. Типы данных SQL и C++ (ODBC)
SQL. Выполнение прямых вызовов SQL (ODBC)