Delphi world - особливості використання blob полів в dbexpress на прикладі mysql

Особливості використання BLOB полів в dbExpress на прикладі MySQL

Використовувати нові компоненти dbExpress зручно. Однак прикметник «нові» приносить не тільки радість ... Рішення виникаючих проблем буває затягується на довгі години і дні. На допомогу Internet жаль сподіватися не доводиться, тому що інформації по dbExpress там ні так багато. Одна з цих проблем - робота з BLOB полями. Використовувати нативний SQL для роботи з BLOB не завжди можливо, тому потрібно застосовувати інші, альтернативні способи.

Для роботи з BLOB полями в Delphi є кілька класів:

  • TBlobStream;
  • TClientBlobStream;
  • TBlobField;
  • TGraphicField;
  • TMemoField;

Також сюди можна віднести функцію TCustomClientDataSet.CreateBlobStream, але вона реалізована за допомогою класу TClientBlobStream. Класи TGraphicField і TMemoField є похідними від TBlobField. TBlobStream не підходить для роботи з dbExpress, а застосовується тільки при маніпулюванні даними через BDE.

Таким чином для роботи з BLOB-полями через dbExpress залишаються два ключових класу: TBlobField і TClientBlobStream. Отже можливо два, принципово різних, способи отримати доступ до BLOB-полів: через потоки і через властивості об'єкта. Як зазначено в довідці при роботі з BLOB-полями взагалі і dbExpress зокрема досить зручними виявляються змінні типу String.

Дійсно, максимальний розмір даних, що зберігаються в змінних даного типу становить 2 Гб, що дорівнює максимальному розміру BLOB-поля в MySQL (3.23.47). Рядки досить зручні для роботи з потоками, а також існує досить багато функцій для роботи з ними. Проблем при роботі з BLOB-полями також існує дві: читання даних і їх запис. Розглянемо кожен з можливих варіантів.

Проблема №1. Читання даних з BLOB-поля

Для роботи з BLOB-полями необхідно привласнити властивості TCustomClientDataSet.FetchOnDemand значення True, а також необхідно уважно вивчити властивість Options параметр poFetchBlobsOnDemand. Дані настройки потрібні для того, щоб отримувати дані з BLOB-поля в клієнтську програму. Завантажити дані можна використовуючи метод FetchBlobs.

Використання властивості TDataSet.FieldValues

Використання властивості TBlobField.Value

Проблема №2. Запис даних в BLOB-поле.

При записи даних в BLOB-поле необхідно враховувати, що для внесення змін одного методу Post недостатньо. Для пересилання даних в таблицю після методу Post необхідно викликати метод TCustomClientDataSet.ApplyUpdates. Разом з цим методом корисно використовувати властивість TCustomClientDataSet.ChangeCount, яке містить кількість змін внесених користувачем. У довідковій системі Delphi міститься приклад як спільно використовувати цю властивість і метод ApplyUpdates.

Перед створенням потоку необхідно обов'язково викликати метод FetchBlobs для завантаження даних з BLOB-поля, інакше виникає помилка. При роботі з полем використовуючи потік, необхідно дотримуватися правила:

Одна запис - один потік.

Якщо необхідно обробити новий запис, то потік необхідно створювати заново. Природно потрібно не забувати вчасно знищувати створені потоки.

З незрозумілих причин цей код не працює. Точніше дані в Stream передаються, але в базу не записуються. При цьому ніяких помилок не видається (може це bug, а може щось в даному коді не враховано). У зв'язку з цим, якщо необхідно використання потоків, слід створити проміжний потік, потім завантажити в нього дані, а потім ці дані перекинути в строкову змінну, яку в подальшому занести в базу. Цей спосіб не є найоптимальнішим, але працює безвідмовно.