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


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

Примечание.

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

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

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

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

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

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

Регистр То, что вы передаете в lpszSQL Результирующая инструкция SELECT
1 NULL SELECT rfx-field-list FROM table-name

CRecordset::Open вызовы GetDefaultSQL для получения имени таблицы. Результирующая строка является одним из вариантов от 2 до 5, в зависимости от того, что GetDefaultSQL возвращается.
2 Имя таблицы SELECT rfx-field-list FROM table-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 и/или ORDER BY таким образом, не используйте m_strFilter и /илиm_strSort.

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

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

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

См. также

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