Сохранение в Blob-поля в FireBird

Рейтинг: 0Ответов: 1Опубликовано: 09.11.2014

Имеется таблица:

CREATE TABLE HOOKNAMES (
HN_ID             SMALLINT NOT NULL PRIMARY KEY,
HN_NAME           VARCHAR(20) NOT NULL,
HN_LEVEL          SMALLINT NOT NULL,
HN_IMAGE          BLOB);

Первые 3 поля заполняю так:

Form1.IBSql1.SQL.Clear;
Form1.IBSql1.SQL.Append('INSERT INTO HOOKNAMES (HN_ID, HN_NAME, HN_LEVEL) ');
Form1.IBSql1.SQL.Append('VALUES ('+TempBuf[3]+', '+TempBuf[0]+', '+TempBuf[1]+')');
Form1.IBSql1.ExecQuery;

Последнее поле пробую добавить следующим образом (пример нашёл на этом сайте):

Form1.HookNamesDS.Edit;
TBlobField(Form1.HookNamesDS.FieldByName('HN_IMAGE')).LoadFromFile('..\bilder\image.png');
Form1.HookNamesDS.Post;

Var HookNamesDS: TIBDataSet;

Получаю ошибку при попытке изменить DataSet, который только для чтения, в нём не задан DataSource, просто выбрана вся таблица через SelectSQL.
Каким образом в данном примере идёт привязка именно к нужной строке?
Каким образом нужно правильно инициализировать DataSet? И как правильно с ним работать?

Ответы

▲ 2Принят

Вам сначала надо добиться, чтоб таблица была модифицируемая. Если вы используете TIBDataSet, то необходимо прописать все sql запросы: SelectSQL, ModifySQL, DeleteSQL, InsertSQL. Если вы добавите компонент на форму, можно задать эти запросы в визуальном редакторе (пкм на компоненте, Dataset editor...), выбираете в нем имя таблицы, запросы создадутся, afair сами. Если вы создаете компонент в рантайме, значит надо прописать эти же запросы в коде. Про тексты запросов писал здесь.

После того как вы получите модифицируемый dataset, уже можно приступать к сохранению blob'ов.

UPD По поводу TIBSQL. Никогда не пишите запросы так. Всегда пользуйтесь параметрами.

UPD2 Если вы добавляете или редактируете несуществующую запись (например, таблица пустая - будет вызван Insert), в этом случае вам надо заполнить и HN_ID. Для изменения, как в вопросе, HookNamesDS.Edit - HN_ID у вас для текущей записи должно быть уже заполнено. В любом случае заполнять надо поле, а не параметр. Параметры будут заполняться сами, этим занимается компонент.

with Form1.HookNamesDS do
begin
  Insert;
  FieldByName('HN_ID').AsString:=TempBuf[3];
  // остальные поля
  TBlobField(FieldByName('HN_IMAGE')).LoadFromFile('..\bilder\image.png');
  Post;
end;

А так, должен работать ваш код из вопроса.