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
В следующей таблице показаны возможности для параметра Open
lpszSQL. В таблице описаны случаи, описанные в таблице.
Параметр lpszSQL и результирующая строка SQL
Регистр | То, что вы передаете в lpszSQL | Результирующая инструкция SELECT |
---|---|---|
1 | NULL | SELECT rfx-field-list FROM table-nameCRecordset::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)