Класс CODBCRecordset
Автор: Stefan Chekanov
Скачать исходник - 13 Kb
Описание
В обычном MFC проекте, предназначенном для
работы с базой данных, мы получаем множество
классов, наследованных от CRecordset, которые
генерирует для нас визард (ClassWizard).
Представленный здесь класс CODBCRecordset легко
может заменить все эти CRecordset классы. CODBCRecordset
сам по себе наследуется от CRecordset ,
но не имеет жёско-заданных количества и типов
полей базы данных.
CODBCRecordset имеет как минимум два
преимущества:
- CODBCRecordset может использоваться не токо для
получения значений из базы данных, но и для
записи, используя MFC.
- Другие подобные примеры не могут одновременно
открывать более одной записи через одно
соединение с базой данных, в случае с базой
данных MS SQL Server. В некоторых случаях это вызывает
проблемы, так как открытие нового соединения
довольно продолжительно по времени и требует
значительных затрат ресурсов.
Так как CODBCRecordset наследуется от CRecordset и
использует его механизм обмена данными, то он
полностью совместим с MFC ODBC классом CDatabase .
Каждое значение поля хранится в объекте CDBField .
Класс CDBField унаследован от CDBVariant и
имеет дополнительные функции, которые упрощают
его использование.
Классы CODBCRecordset и CDBField поддерживают
все типы данных. CDBField делает неявное
преобразование типов, в тех местах, где требуется
представить данные в запрошенном формате.
Ниже представлен список методов CODBCRecordset и
CDBField :
Класс
CODBCRecordset |
Конструктор |
Тоже что и для CRecordset принимая CDatabase* |
BOOL Open( LPCTSTR lpszSQL, UINT nOpenType, DWORD
dwOptions ); |
Открывает запись
lpszSQL - это SQL выражение, которое возвращает
запись
т.е. SELECT * FROM tablename
nOpenType тип открытия, см. CRecordset::Open()
dwOptions опции для CRecordset , см. CRecordset::Open()
Обратите внимание, что lpszSQL и nOpenType поменялись
местами, если сравнивать с CRecordset::Open () |
short GetODBCFieldCount()
|
Возвращает количество полей (колонок) в
записи. Данный метод определён в CRecordset . |
int GetFieldID( LPCTSTR )
|
Возвращает индекс поля для данного
имени поля. Не чувствителен к регистру. Напротив, CRecordset::GetFieldIndexByName()
чувствителен к регистру. |
CString GetFieldName( int )
|
Возвращает имя поля для данного индекса
поля |
CDBField& Field( LPCTSTR )
CDBField& Field( int ) |
По средствам этого метода можно
получить ссылку на внутренний объект CDBField ,
отвечающий за определённую колонку (См. класс CDBField
). Данный метод может использоваться в двух
вариациях - с аргументом типа LPCTSTR szName ,
указывающем имя колонки, и int nID , указывающем
индекс колонки в записи. |
CDBField& operator(
LPCTSTR )
CDBField& operator( int
) |
Оператор функции служит для облегчения
использования класса и для вызова
соответствующего метода Field() параметр
типа LPCTSTR szName - указывает на имя колонки, а int
nID - на индекс колонки. |
bool |
GetBool() |
unsigned char
|
GetChar() |
short |
GetShort() |
int |
GetInt() |
long |
GetLong() |
float |
Getfloat() |
double |
GetDouble() |
COleDateTime |
GetDate() |
CString |
GetString() |
CLongBinary* |
GetBinary() |
|
Каждый из этих методов делает
соответствующее преобразование, в зависимости
от возвращаемых значений и типов данных. Эти
методы вызывают Field().AsXXX()
(См. класс CDBField).параметр типа LPCTSTR szName -
указывает на имя колонки, а int nID - на индекс
колонки. |
Класс
CDBField |
Конструкторы |
Здесь не присутствует конструкторов
public. CDBField нельзя использовать без CODBCRecordset,
так как внутренние структуры и объекты доступны
через методы CODBCRecordset . |
bool |
AsBool() |
unsigned char
|
AsChar() |
short |
AsShort() |
int |
AsInt() |
long |
AsLong() |
float |
AsFloat() |
double |
AsDoble() |
COleDateTime |
AsDate() |
CString |
AsString() |
CLongBinary* |
AsBinary() |
|
Каждый из этих методов делает
соответствующее преобразование, в зависимости
от возвращаемых значений и типов данных. (См.
таблицу методов AsXXX, для более детального
ознакомления с правилами преобразования). Здесь
нет типа данных Int , а AsInt()
эквивалентен AsLong() |
операторы аргументов |
(См. таблицу операторов аргументов для
ознакомления с правилами преобразования). |
const CString& GetName()
|
Возвращает имя поля, которому
соответствует данный объект. |
bool |
IsNull() |
bool |
IsBool() |
bool |
IsChar() |
bool |
IsShort() |
bool |
IsInt() |
bool |
IsLong() |
bool |
IsFloat() |
bool |
IsDouble() |
bool |
IsNumber() |
bool |
IsDate() |
bool |
IsString() |
bool |
IsBinary() |
|
Каждый из них возвращает true если
поле содержит значение соответствует типу
данных.
Здесь нет типа данных Number , а IsNumber()
возвращает true если IsShort() || IsLong() || IsFloat() || IsDouble() .
Здесь нет типа данных Int , а IsInt()
возвращает true если IsLong() возвращает true. |
Преобразования
делаемые методами AsXXX |
|
Значения
в базе данных |
|
NULL |
BOOL |
UCHAR |
SHORT |
LONG |
SINGLE |
DOUBLE |
DATE |
STRING |
BINARY |
AsBool |
false |
* |
* |
* |
* |
* |
* |
|
* |
|
AsChar |
0x32 |
* |
* |
* |
* |
* |
* |
|
* |
|
AsShort |
0 |
* |
* |
* |
* |
* |
* |
|
* |
|
AsInt |
0 |
* |
* |
* |
* |
* |
* |
|
* |
|
AsLong |
0 |
* |
* |
* |
* |
* |
* |
|
* |
|
AsFloat |
0.0 |
* |
* |
* |
* |
* |
* |
|
* |
|
AsDouble |
0.0 |
* |
* |
* |
* |
* |
* |
|
* |
|
AsDate |
null |
invalid |
invalid |
* |
* |
* |
* |
* |
* |
|
AsString |
empty |
* |
* |
* |
* |
* |
* |
* |
* |
* |
AsLongBinary |
NULL |
|
|
|
|
|
|
|
|
* |
Пустые ячейки, указывают на то, что
данное преобразование невозможно.
Ячейки, помеченные как * указывают на
допустимость данной операции (См. таблицу
алгоритмов преобразования). |
Conversions
made by assignment operators |
Тип поля базы
данных |
Аргумент
оператора |
|
bool |
unsigned
char |
short |
int |
long |
float |
double |
COleDateTime |
String |
NULL |
|
|
|
|
|
|
|
|
|
BOOL |
* |
* |
* |
* |
* |
* |
* |
|
* |
UCHAR |
* |
* |
* |
* |
* |
* |
* |
|
* |
SHORT |
* |
* |
* |
* |
* |
* |
* |
|
* |
LONG |
* |
* |
* |
* |
* |
* |
* |
|
* |
SINGLE |
* |
* |
* |
* |
* |
* |
* |
|
* |
DOUBLE |
* |
* |
* |
* |
* |
* |
* |
|
* |
DATE |
|
|
|
|
|
|
|
* |
* |
STRING |
* |
* |
* |
* |
* |
* |
* |
* |
* |
BINARY |
|
|
|
|
|
|
|
|
|
Пустые ячейки, указывают на то, что
данное преобразование невозможно.
Ячейки, помеченные как * указывают на
допустимость данной операции (См. таблицу
алгоритмов преобразования). |
Алгоритмы
преобразования |
String в Bool |
Сравнение первого символа строки с 'T' |
Char в Bool |
Сравнение символа с 'T' |
Bool в String |
String = (bVal) ? 'T' : 'F' |
Bool в Char |
Char = (bVal) ? 'T' : 'F' |
String в Number |
использование функции atoX() |
Number в String |
метод CString::Format(), используя
соответствующий формат строки |
String в Date |
метод COleDateTime::ParseDateTime() |
Date в String |
метод COleDateTime::Format() |
Пример использования CODBCRecordset
Вам необходимо включить в Ваш проект файлы ODBCRecordset.h и ODBCRecordset.cpp.
Обычно я добавляю следующую строчку в мой файл StdAfx.h.
#include "ODBCRecordset.h"
Далее следует простой код, показывающий как
можно использовать CODBCRecordset.
CDatabase db;
CString cConnect = "ODBC;";
db.Open( NULL,
FALSE,
FALSE,
cConnect,
TRUE
);
COleDateTime dOrderDate;
CODBCRecordset rs( &db );
rs.Open( "SELECT * FROM Orders \
WHERE ORDER_DATE > 'jan 1 2000' \
ORDER BY ORDER_DATE" );
for( ; ! rs.IsEOF(); rs.MoveNext() )
{
dOrderDate = rs.GetDate( "ORDER_DATE" );
dOrderDate = rs.Field("ORDER_DATE").AsDate();
dOrderDate = rs("ORDER_DATE");
dOrderDate = rs.Field("ORDER_DATE");
rs.Edit();
rs("ORDER_DATE") = "jan 1 1999";
rs.Field("ORDER_DATE") = "jan 1 1999";
rs.Update();
}
Если ORDER_DATE хранится в базе данных как datetime
либо совместимым типом данных, то значение
будет браться напрямую.
Если ORDER_DATE хранится в базе данных как string
либо совместимым типом данных (char, varchar), то
значение будет преобразовано через метод COleDateTime::ParseDateTime() .
Если преобразование не удалось, то dOrderDate
будет установлен в COleDatetime::invalid .
При работе с базой данных, может возникнуть так,
что 2 или более колонок могут иметь одинаковые
имена. CODBCRecordset оставляет имя первого
столбца нетронутым, но другие повторяющиеся
колонки переименованы путём добавления номера
этой колонки. Например:
SELECT * FROM Orders, Customers WHERE Orders.CUST_ID = Customers.ID
Если таблица Orders имеет колонку с именем ID
, и Customers имеет колонку с именем ID , то CODBCRecordset
переименует ID из Customers в ID2 , а все
остальные, неповторяющиеся столбцы останутся не
тронутыми.
Например: Переименуем колонки в ручную, чтобы
быть уверенными в именах
SELECT Orders.*, Customers.ID as CUSTOMERS_ID
FROM Orders, Customers
WHERE Orders.CUST_ID = Customers.ID
|