- •О.С. Зеленський
- •Розділ 9. Структура створення додатків
- •9.1. Загальна структура додатків
- •9.2. Додатки без використання архітектури «Документ-вид»
- •9.2.1. Приклад додатку реєстрації wnd-класу вікна
- •9.2.2. Створення та видалення дочірніх вікон без використання архітектури «Документ-Вид»
- •9.2.3. Створення дочірніх вікон без використання архітектури «Документ-Вид» (переключення вікон з використанням функції ShowWindow)
- •9.3. Архітектура «Документ-Вид»
- •Idr_mainframe формат строкового ресурсу.
- •9.3.1. Приклад додатку з використанням архітектури «Документ-Вид»
- •9.3.2. Види у архітектурі «Документ-Вид»
- •9.3.3. Створення видів у архітектурі «Документ-Вид» (переключення видів з використанням функції ShowWindow)
- •9.3.4. Робота з документами та видами на прикладі додатку SingleTemplate
- •9.4. Додатки mdi, робота з шаблонами
- •9.4.1. Приклад додатку mdi з одним шаблоном
- •9.4.2. Приклад додатку mdi з декількома шаблонами
- •Контрольні питання
- •Розділ 10. Робота з базами даних з використанням об'єктів ado
- •10.1.1. Ініціалізація об'єктів com з використанням директиви #import
- •10.1.2. Підтримка класів сом
- •10.2. Об'єкт Connection
- •10.3. Об'єкт Command
- •10.4. Об'єкт Recordset
- •10.5. Об'єкт Field і колекція Fields
- •10.6. Об'єкт Error і колекція Errors
- •10.8. Коротка характеристика структури мови sql
- •10.9. Синтаксис оператора вибору Select
- •10.10. Приклад програмування об'єктів ado
- •10.11. Опис розробленого навчального пакету ado6 для роботи з базами даних access та MySql
- •Int tip_bd; // тип бд 1- ms access, 2- MySql, 3 - xml
- •Void Connect_Baza(cString str);
- •Void ErrMessage(_com_error &ce);
- •If(pConn.CreateInstance("adodb.Connection"))
- •If(pRecordset.CreateInstance("adodb.RecordSet"))
- •Void cAdo6Doc::ErrMessage(_com_error &ce)
- •Void cAdo6Doc::OnMsaccess()
- •Void cAdo6Doc::OnMysql()
- •Void cAdo6Doc::OnXmlRead()
- •Void cAdo6Doc::Connect_Baza(cString str)
- •Virtual void DoDataExchange(cDataExchange* pDx);
- •Void cAdo6Dlg::DoDataExchange(cDataExchange* pDx)
- •Void cAdo6Dlg::Struct_MySql()
- •Void cAdo6Dlg::OnSelchangeListBaza()
- •Void cAdo6Dlg::OnVibor_bd()
- •Void cAdo6Dlg::AccessOpen()
- •Void cAdo6Dlg::xmlOpen()
- •Void cAdo6Dlg::Structura_bd()
- •Void cAdo6Dlg::OnSelchangeListTab()
- •Void cAdo6Dlg::show(int kod, int kod_bd)
- •Void cAdo6Dlg::Recordset_Baza(cString str)
- •Void cAdo6Dlg::OnClose()
- •10.11.2. Формування списку бд (MySql), відкриття бази даних (ms access), відкриття xml-файлу, формування списку таблиць (MySql і ms access) та полів (MySql, ms access, xml)
- •Void cAdo6Dlg::OnSelchangeListTab()
- •1. Обрану таблицю необхідно брати в зворотні лапки "`", щоб виключити помилку в тому випадку, якщо в імені таблиці будуть зустрічатися пробіли.
- •10.11.3. Робота з sql-запитами
- •Void cAdo6Dlg::OnZapros_Select()
- •If (str_query.Mid(0,6).Compare("select"))
- •If(!baza.Left(3).Compare("otl") &&
- •Void cAdo6Dlg::Recordset_Baza(cString str)
- •Void cado6Dlg::OnZapros_Make()
- •Vr_zap.Format(" Запрос выполнен за %f сек ",conec - nach);
- •10.11.4. Видалення, сортування, пошук, фільтрація, оновлення набору записів
- •Void cado6Dlg::OnZapis_Delete()
- •Void cado6Dlg::OnCheck_Sort()
- •Void cado6Dlg::OnFind()
- •0L,adSearchForward,bb);
- •Void cado6Dlg::OnFilter()
- •Void cado6Dlg::OnVozvrat()
- •10.11.5. Переходи по записах
- •Void cado6Dlg::OnButtonFirst()
- •Void cado6Dlg::OnButtonLast()
- •Void cado6Dlg::OnButtonLeft()
- •Void cado6Dlg::OnButtonRight()
- •Void cado6Dlg::OnButtonRecno()
- •Void cado6Dlg::OnButtonPgup()
- •Void cado6Dlg::OnButtonPgdn()
- •Void cado6Dlg::OnButtonBookmark()
- •10.11.6. Запис даних до xml-файлу
- •Void cAdo6Dlg::OnButtonSave()
- •10.11.7. Кнопки, призначені тільки для роботи з otl_tab
- •Void cado6Dlg::OnZapis_Add1()
- •Void cado6Dlg::OnZapis_Add2()
- •Void cado6Dlg::OnZapis_Update1()
- •Void cado6Dlg::OnZapis_Update2()
- •Void cado6Dlg::OnFormir_bd()
- •Void cAdo6Dlg::OnValues_Fields()
- •10.12. Використання у якості джерела даних електронної таблиці Excel
- •Контрольні питання
- •Завдання
- •Розділ 11. Програмування для інтернет
- •11.1. Створення броузера
- •11.3. Використання протоколу http
- •If ((pInternetSession)
- •11.4. Використання протоколу ftp
- •Контрольні питання
- •Розділ 12. Створення елементів activex
- •12.1. Створення елементів ActiveX
- •Invalidate();
- •12.2. Тестування елемента ActiveX
- •12.4. Створення елемента ActiveX на базі стандартних елементів
- •12.5. Відображення елементів ActiveX
- •Контрольні питання
- •Розділ 13. Налагодження програм
- •Int data[5];
- •Invalidate();
- •13.3. Установка точки переривання
- •13.2. Покрокове виконання програми
- •13.4. Перевірка значень змінних під час виконання програми
- •Контрольні питання
- •Список літератури
- •Додатки
10.4. Об'єкт Recordset
Об'єкт Recordset забезпечує взаємодію з даними. Він використовується для зберігання набору записів, що повертається з джерела даних. Набір записів можна відкрити безпосередньо, викликавши метод Open(), або можна згенерувати набір записів за допомогою виклику методу Execute() для об'єкта з'єднання або команди.
Об'єкт Recordset містить всі записи, які повертаються з джерела даних, однак в кожний момент часу можна працювати лише з одним поточним записом. Даними запису можна маніпулювати за допомогою об'єктів Field, що містяться в колекції Fields.
Доцільно створювати набір Recordset за допомогою об'єкта Recordset, використовуючи метод Open(). Це дозволяє створювати набір даних, як на сервері, так і на місці клієнта. В останньому випадку значно оперативніше обробляються дані, а також є можливість підключати різні ActiveX-компоненти, які використовують набір Recordset з боку клієнтської частини. Можна створювати об'єкти Recordset і з допомогою об'єктів Connection і Command, використовуючи метод Execute(). Однак у цьому випадку місце розташування набору даних залежить від властивості CursorLocation об'єкта Connection, успадкованого всіма об'єктами Recordset. За замовчуванням всі курсори встановлені з боку сервера. Вдалим підходом є комбіноване використання об'єктів Connection-Recordset, Command-Recordset, Connection-Command-Recordset. Кожен з цих об'єктів має свої переваги, відповідно при підключенні, виконанні команд і роботою з набором даних.
Скажімо, для першої пропонованої пари об'єктів, доцільно виконати підключення в об'єкті Connection, а використовуючи його метод Execute(), виконувати команди без використання SQL-запитів на вибірку. Перевага виконання таких команд, як було зазначено вище, полягає у можливості виконання транзакцій. Формування ж набору даних доцільно виконати в об'єкті Recordset (метод Open()). При цьому використовувати як параметр ActiveConnection методу Open() об'єкт Connection, тобто використовувати раніше створене підключення до джерела даних.
У таблицях 10.5, 10.6 наведено відповідно основні властивості і методи об'єкта Recordset.
Таблиця 10.5
Властивості об'єкта Recordset
Властивості |
Опис |
ActiveConnection |
Містить об'єкт Connection, до якого прив'язаний даний Recordset, або рядок параметрів підключення (ConnectionString). |
ActiveCommand |
Містить об'єкт Command. Якщо об'єкт Command не використовувався, то містить пусте значення. |
Source |
Містить джерело даних об'єкта Recordset. Це посилання на об'єкт Command, оператор SQL, ім'я таблиці або збереженої процедури. Властивості можна задати значення тільки перед відкриттям об'єкта Recordset. |
Filter |
Містить фільтр даних. Може приймати значення наступних типів:
Необхідно використовувати цю властивість для вибіркового сканування об'єкта Recordset. Установка властивості перемістить курсор на перший запис, яка задовольняє фільтру. |
CursorLocation |
Визначає розташування курсору (на сервері або на клієнті). Доступно для встановлення тільки до здійснення підключення до джерела даних. Можливі значення:
|
CursorType |
Містить тип курсора. Може бути змінена тільки до відкриття об'єкта Recordset. Можливі значення:
|
LockType |
Задає тип блокування, що використовується при відкритті провайдером рядків даного набору записів. Можливі значення:
|
MaxRecords |
Необхідно використовувати цю властивість для обмеження кількості записів, які повертає провайдер в результаті запиту до джерела даних. За замовчуванням - повертаються всі потрібні записи. |
CacheSize |
Встановлює кількість записів об'єкта Recordset (обов'язково більше 0), які кешуються (локально) в пам'яті. Значення за замовчуванням 1. Наприклад, якщо CacheSize = 10, то після відкриття об'єкта Recordset провайдер поміщає перші 10 записів в локальну пам'ять. У міру того, як відбувається рух по записах об'єкта Recordset, провайдер повертає дані з локального буфера пам'яті. Як тільки промине останній запис в кеші, провайдер поміщає наступні 10 записів з джерела даних у кеш. Записи в кеші не відображають зміни, які роблять інші користувачі. Щоб викликати модифікацію всіх кешованих даних, необхідно використовувати метод Resync(). |
RecordCount |
Повертає кількість записів в об'єкті Recordset. Якщо провайдер або тип курсору не підтримує дану властивість, то повертає -1. |
BOF ADO_EOF |
Якщо властивість BOF дорівнює true, то поточний запис знаходиться перед першим записом в об'єкті Recordset. Якщо властивість ADO_EOF дорівнює true, то поточний запис знаходиться після останнього запису в об'єкті Recordset. При відкритті порожнього об'єкта Recordset обидві ці властивості рівні true. |
Продовження таблиці 10.5
Властивості |
Опис |
AbsolutePosition |
При установці переміщує курсор на запис під даним номером. Доступно не для всіх типів курсорів. Значення в інтервалі з 1 по RecordCount. Властивість підтримується не всіма провайдерами. |
Bookmark |
Закладка у вигляді числа. Доступно не для всіх видів курсорів. Дає можливість при проході по таблиці запам'ятати значення Bookmark в тимчасовій змінній, а потім повернутися назад на цей запис шляхом установки властивості з цієї змінної. Закладка унікально ідентифікує запис. При початковому відкритті набору закладка відповідає номеру фізичного запису. Якщо в об'єкті Recordset будуть видалені окремі записи - номери закладок не зміняться - і посилання на старі записи стане неможливим. При оновленні Recordset формуються нові, суворо впорядковані закладки. Властивість Bookmark має тип даних _variant_t, містить тип double. |
PageSize |
Визначає кількість записів на сторінці. За замовчуванням - 10. Доступно не для всіх видів курсорів. |
PageCount |
Повертає кількість сторінок. Автоматично перераховується при зміні PageSize. Доступно не для всіх видів курсорів. |
AbsolutePage |
При установці переміщує курсор на початок даної сторінки. Доступно не для всіх типів курсорів. Значення в інтервалі з 1 по PageCount. Властивість підтримується не всіма провайдерами. |
EditMode |
Повертає стан редагування поточного запису (чи був викликаний метод Update() або UpdateBatch() для збереження змін). Можливі значення:
|
Таблиця 10.6
Методи об'єкта Recordset
Методи |
Опис |
Open(Source, ActiveConnection, CursorType, LockType, Options) |
Відкриває курсор. Параметри:
За замовчуванням Recordset буде відкритий з курсором, який можна переглянути тільки зверху вниз (forward-only), тільки для читання (read-only) на стороні сервера. |
Close() |
Закриває об'єкт Recordset. Якщо об'єкт Recordset закривається в пакетному режимі модифікації, то всі зміни після останнього виклику UpdateBatch() будуть втрачені. |
Requery(Options) |
Оновлює дані в об'єкті Recordset шляхом повторного виконання запиту. Еквівалентно викликам Close(), а потім Open(). |
Resync(AffectRecords, ResyncValues) |
Оновлює дані в об'єкті Recordset. Не виконує повторного запиту до бази даних, тому знову додані записи не будуть видимі. Якщо існуючі записи були вилучені з бази даних, то відбудеться помилка. Цей метод зазвичай використовують зі статичним курсором або курсором типу зверху-вниз (forward-only), щоб бачити зміни, внесені в базу даних. Параметри:
|
Save(FileName, PersistFormat) |
Зберігає набір записів у файл. Викликається тільки для відкритого набору записів. Після виклику методу поточним стає перший рядок набору записів. Параметри:
Якщо встановлено властивість Filter, то будуть збережені тільки записи, що задовольняють фільтру. |
Move(NumRecords, Start) |
Пересуває позицію поточного запису в наборі записів. Параметри:
Виклик методу для порожнього набору записів призведе до помилки. |
MoveFirst() MoveLast() MoveNext() MovePrevious() |
Пересувають позицію поточного запису відповідно на перший, останній, наступний або попередній запис. Виклик MoveFirst() в об'єкті Recordset типу зверху-вниз (forward-only) може змусити провайдера заново виконати команду, яка згенерувала цей Recordset. |
Delete(AffectRecords) |
Видаляє поточний запис або групу записів. Якщо об'єкт Recordset не допускає видалення записів, то відбудеться помилка. Якщо виконується пакетний режим модифікації, то фактичне видалення відбувається при виклику UpdateBatch(). Можна також скасувати видалення викликом CancelBatch(). Параметр AffectRecords може приймати значення:
|
AddNew(Fields, Values) |
Додає запис із зазначеними значеннями полів в кінець об'єкта Recordset і робить його поточним. Параметри:
Щоб зберегти доданий запис, необхідно викликати метод Update(). При безпосередньому режимі модифікації, якщо передаються параметри Fieldlist і Values, то ADO негайно відправляє новий запис в базу даних (виклик Update() не потрібний). У пакетному режимі модифікації для збереження запису в базі даних необхідно викликати метод UpdateBatch(). При виклику методу AddNew() без параметрів додається новий порожній запис і стає поточним. |
Update(Fields, Values) |
Зберігає будь-які зміни поточного запису об'єкта Recordset. Параметри:
Якщо курсор переміщений з доданим або зміненим записом, то метод викликається автоматично. При виклику методу Update() без параметрів оновлюється поточний запис. |
CancelUpdate() |
Відміняє будь-які зміни або додавання записів, проведені до використання методу Update(). |
UpdateBatch(AffectRecords, PreserveStatus) |
Для пакетного режиму модифікації: записує всі зміни об'єкта Recordset в базу даних. Тільки для курсорів типу Keyset або Static. Щоб скасувати всі пакетні модифікації які очікують дозволу, необхідно використовувати метод CancelBatch(). Порядок, в якому модифікації виконуються на джерелі даних, не обов'язково той же, в якому ці модифікації були виконані в поточному об'єкті Recordset. Параметри:
|
CancelBatch(AffectRecords) |
Відміняє будь-які модифікації які очікують дозволу в пакетному режимі модифікації. Обробка помилок аналогічна методу UpdateBatch(). Необов'язковий параметр AffectRecords вказує, яких записів торкнеться метод. Можливі значення - див. опис аргументу AffectRecords методу Resync(). |
Fields |
Містить колекцію полів (об'єктів Field). |
Properties |
Містить колекцію динамічних властивостей об'єкта (об'єктів Property). |
Sort |
Рядок, що містить одне або більше імен полів, за якими слід відсортувати Recordset, і порядок сортування (за зростанням або за спаданням). Кожне ім'я поля відокремлюється комою і довільно супроводжується пробілом і ключовим словом ASC, яке сортує в зростаючому порядку, або DESC, яке сортує за спаданням. За замовчуванням сортування відбувається у зростаючому порядку. Ця властивість вимагає, щоб властивість CursorLocation була встановлено в adUseClient(3). Ця властивість має пріоритет перед пропозицією ORDER BY, включеною до інструкції SQL. Установка властивості до порожнього рядку скине рядки до їх первісного порядку. Сортування створює тимчасові відкриті індексні файли до набору, що дозволяє ефективно здійснити пошук, використовуючи метод Find. |
NextRecordset(RecordsAffected) |
Використовується для переміщення до наступного набору записів, повертається, складовими запитами. Він очищає набір записів і повертає дані для наступного згенерованого набору записів. |
Supports(CursorOptions) |
Визначає, чи підтримує поточний курсор Recordset специфічний тип функціональних можливостей і повертає логічне значення. Параметр CursorOptions складається з одного або більше значень:
|
Find(Criteria, SkipRows, SearchDirection, Start) |
Шукає в Recordset рядок, який задовольняє вказаним критеріям. Якщо рядок знайдений, то він стає поточним. Інакше, поточна позиція встановлюється на кінець (або початок) Recordset. Перед викликом методу поточна позиція повинна бути встановлена. Параметри:
|
GetRows(Rows, Start, Fields) |
Поміщає запису об'єкта Recordset в масив. Повертає двовимірний масив. Параметри:
|
GetString(StringFormat, NumRows, ColumnDelimiter, RowDelimiter, NullExpr) |
Повертає Recordset як рядок. Параметри:
|
Розглянемо приклади роботи з об'єктом Recordset.
Приклад 1. Створення об'єкта Recordset з використанням об'єкта Connection.
.............................................................
_ConnectionPtr pConn;
pConn.CreateInstance("ADODB.Connection");
pConn->Mode=adModeReadWrite;
pConn->Open("Provider=Microsoft.Jet.OLEDB.4.0;
Data Source=C:\\VCCP\\ADO\\NWIND.MDB;","admin","",0);
_RecordsetPtr pRsProducts;
pRsProducts = pConn->Execute((_bstr_t) "SELECT * FROM Products", 0, adCmdUnknown);
.............................................................
pRsProducts->Close();
pConn->Close();
.............................................................
Приклад 2. Створення об'єкта Recordset з використанням тільки об'єкта Recordset.
.............................................................
RecordsetPtr pRsProducts("ADODB.Recordset");
pRsProducts->Open("SELECT * FROM Products","DRIVER=Microsoft Access Driver (*.mdb); DBQ=D:\\VC6\\NWIND.MDB", adOpenStatic,adLockOptimistic,adCmdText);
.............................................................
pRsProducts->Close();
.............................................................
Приклад 3. Створення об'єкта Recordset з використанням об'єкта Command.
У прикладі використовується запит "Invoices" в базі даних nwind.mdb (збережена процедура).
.............................................................
_CommandPtr pCommand ("ADODB.Command");
pCommand->ActiveConnection = “Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\VCCP\\ADO\\NWIND.MDB”;
pCommand->PutCommandText("Invoices");
_RecordsetPtr pRsSales;
pRsSales = pCommand->Execute(0,0,adCmdStoredProc);
.............................................................
pCommand->Close();
.............................................................
Приклад 4. Створення об'єкта Recordset з використанням об'єктів Connection-Command.
.............................................................
_ConnectionPtr pConn("ADODB.Connection");
pConn->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\VCCP\\ADO\\NWIND.MDB" ","","",0);
_CommandPtr pCommand ("ADODB.Command");
pCommand->ActiveConnection = pConn;
_RecordsetPtr pRsSales;
pRsSales=pCommand->Execute(0,0,adCmdStoredProc);
.............................................................
pConn->Close();
.............................................................
Приклад 5. Створення об'єкта Recordset з використанням об'єктів Connection-Recordset.
.............................................................
_ConnectionPtr pConn;
pConn.CreateInstance("ADODB.Connection");
pConn->Mode=adModeReadWrite;
pConn->Open("Provider=Microsoft.Jet.OLEDB.4.0;
Data Source=C:\\VCCP\\ADO\\NWIND.MDB;","admin","",0);
_RecordsetPtr pRsProducts("ADODB.Recordset");
pRsProducts->CursorLocation = adUseClient;
pRsProducts->Open((_bstr_t) “SELECT * FROM Products”, (IUnknown *) pConn, adOpenStatic,adLockOptimistic,adCmdText);
.............................................................
pRsProducts->Close();
pConn->Close();
.............................................................
Нижче розглядаються приклади роботи із записами об'єкту Recordset (переміщення, видалення, перехід до зазначеного запису, перехід до зазначеної закладки, сторінки).
У наведених нижче фрагментах прикладів мається на увазі, що об'єкт Recordset вже створений.
Приклад 6. Переміщення по записах об'єкта Recordset
.............................................................
pRsProducts->MoveFirst(); // перехід на перший запис
pRsProducts->MoveLast(); // перехід на останній запис
pRsProducts->MoveNext(); // перехід на наступний запис
pRsProducts->MovePrevious(); // перехід на попередній запис
pRsProducts->Move(5); //перехід на 5 записів вниз
// відносно поточного
pRsProducts->Move(-5); //перехід на 5 записів вверх
// відносно поточного
.............................................................
Увага: Якщо об'єкт Recordset створений за допомогою об'єкта Connection (метод Execute()), то курсор створюється згідно успадкованої властивості CursorLocation об'єкта Connection (за замовчуванням - на сервері), тип блокування буде встановлено лише для читання (властивість LockType дорівнює adLockReadOnly), а тип курсору буде встановлено лише для перегляду в один бік - зверху вниз (властивість CursorType дорівнює adOpenForwardOnly). Тобто, в цьому випадку метод MovePrevious - перехід на попередній запис і метод Move з від'ємним значенням - працювати не будуть. Для використання цих та багатьох інших методів і властивостей (використання закладок, сортування, фільтрація) і повної установки властивостей набору, Recordset необхідно створювати за допомогою об'єкту Recordset (метод Open()).
Приклад 7. Перехід на зазначену позицію (рядок) в наборі Recordset
Слід зазначити, що установка абсолютних позицій для переміщення на зазначений запис або сторінку (властивості AbsolutePosition, AbsolutePage) для входу вимагають структуру типу PositionEnum. У даному випадку реалізований універсальний підхід, щоб мати можливість користуватися, як переліком константами enum, так і своїми власними цілими значеннями. Так, у нашому випадку, для переходу на другий запис необхідно число 2 призвести до типу (PositionEnum).
.............................................................
// використання властивості AbsolutePosition для переходу
// на другий запис
pRsProducts->AbsolutePosition = (PositionEnum)2;
// використання функції PutAbsolutePosition для переходу
// на другий запис
pRsProducts->PutAbsolutePosition((PositionEnum)2);
.............................................................
Для того щоб дізнатися поточну позицію в наборі, можна скористатися функцією GetAbsolutePosition(), яка повертає ціле значення типу PositionEnum.
.............................................................
PositionEnum tt;
tt = pRsProducts->GetAbsolutePosition();
.............................................................
Приклад 8. Робота зі сторінками в об'єкті Recordset
При роботі з набором даних, надається можливість працювати зі сторінками об'єкта Recordset. Це дуже зручно при редагуванні даних і посторінковому перегляді. Для того щоб працювати зі сторінками необхідно встановити кількість записів на сторінці - властивість PageSize. Тоді, у властивості PageCount об'єкта Recordset, автоматично відбудеться перерахунок сторінок. За умовчанням число записів на сторінці - 10.
Приклад встановлення кількості записів на сторінці:
.............................................................
pRsProducts->PageSize = 20; // використання властивості
// PageSize для установки 20 записів на сторінці
pRsProducts->PutPageSize(20); // використання функції
// PutPageSize для установки 20 записів на сторінці
.............................................................
Для переходу на вказану сторінку можна скористатися властивістю AbsolutePage, яка також вимагає змінну типу PositionEnum (див. приклад 7).
.............................................................
pRsProducts->AbsolutePage = (PositionEnum)3;
// використання властивості AbsolutePage для переходу
// на третю сторінку
pRsProducts->PutAbsolutePage((PositionEnum)3);
// використання функції PutAbsolutePage для переходу
// на третю сторінку
.............................................................
Для того щоб дізнатися поточну сторінку в наборі, можна скористатися функцією GetAbsolutePage(), яка повертає ціле значення типу PositionEnum.
.............................................................
PositionEnum tt;
tt = pRsProducts->GetAbsolutePage();
.............................................................
Приклад 9. Робота із закладками в об'єкті Recordset
Дані (Bookmark) призначені для збереження поточної позиції запису, з наступним переходом на неї. Bookmark - унікальне значення, яке присвоюється кожному запису. При початковому завантаженні Recordset - Bookmark відповідає порядковому номеру запису. Коли ж відбувається видалення, сортування записів - закладки не перебудовуються. Вони перебудовуються в тому випадку, коли Recordset знову перечитується, що еквівалентно відкриттю набору заново. Тобто, закладки формуються тільки один раз, при формуванні набору. Можна сказати, що закладки при початковому формуванні Recordset відповідають фізичному номеру запису.
Слід відзначити, що тип властивості BookMark - _variant_t, який включає в себе тип даних double.
Приклад переходу на 3-й запис у початковому відкритому наборі.
.............................................................
pRsProducts->Bookmark = 3.0; // використання властивості
// Bookmark для переходу на третій запис
pRsProducts->PutBookmark(3.0); // використання функції
// PutBookMark для переходу на третій запис
.............................................................
Для того щоб взяти поточну закладку в наборі, можна скористатися функцією GetBookmark(), яка повертає значення типу _variant_t.
.............................................................
_variant_t tt;
tt = pRsProducts->GetBookmark();
.............................................................
Приклад 10. Видалення записів в об'єкті Recordset
Для видалення записів призначений метод Delete(). В якості вхідного параметра AffectRecords може бути adAffectCurrent - видалення поточного запису, adAffectGroup - видаляє всі рядки, відповідні властивості Filter, adAffectAll - видаляє всі записи.
.............................................................
pRsProducts->Delete(adAffectCurrent);
// видалення поточного запису
.............................................................
Приклад 11. Додавання пустого і оновлення поточного запису Recordset здійснюється, відповідно за допомогою методів AddNew() та Update().
.............................................................
pRsProducts->AddNew(); // створення нового пустого запису
pRsProducts->Update(); // обновлення поточного запису
.............................................................
Детальна реалізація властивостей і методів об'єктів Connection і Recordset, таких як сортування, фільтрація записів, пошук по заданому значенню і багато іншого, будуть розглянуті у п. 10.11 посібника, які присвячені практичній реалізації технології ADO.
ОСОБЛИВОСТІ РОБОТИ З ОБ'ЄКТОМ RECORDSET !!! Об'єкт Recordset можна формувати за допомогою об'єктів Connection, Command, Recordset. Формування об'єкта Recordset за допомогою методу Execute об'єктів Connection і Command рекомендується використовувати для SQL-запитів на виконання, тобто всіх SQL-запитів без запитів на вибірку. Запит на вибірку доцільно формувати з використанням об'єкта Recordset (метод Open()), який містить значно більше параметрів з набором даних, наприклад редагування БД через набір Recordset. Це дозволяє значно оперативніше обробляти дані.
Важливим моментом при редагуванні даних є тип блокування (оптимістичне і песимістичне). Коли курсор знаходиться на стороні клієнта, доцільно використовувати тільки оптимістичне блокування, тобто записи блокуються при збереженні (метод Update()) для того щоб в момент збереження користувач не міг редагувати дані. Песимістичне блокування доцільно використовувати, коли курсор знаходиться тільки на стороні сервера. У цьому випадку доступ до редагованим записів БД іншим користувачам буде закритий, починаючи від моменту редагування записів, і закінчуючи їх збереженням. При застосуванні песимістичного блокування на стороні клієнта блокується власний набір Recordset - що не має сенсу.