powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Сохранение бинарных данных
25 сообщений из 52, страница 1 из 3
Сохранение бинарных данных
    #39716849
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нужно в базу записывать небольшие куски (до 60 байт) бинарных данных. Также на это поле нужен уникальный ключ.

Создал в базе поле
Код: sql
1.
DATA  VARCHAR(60) CHARACTER SET NONE


А как теперь записать в него данные, при условии, что в подключении указано
Код: sql
1.
lc_ctype=WIN1251



Как пробовал
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
IBDataSet1.FieldByName('Data').AsString := #130#131#132;
//============
IBDataSet1.FieldByName('Data').AsAnsiString := #130#131#132;
//============
SetLength(LData, 3);
LData[0] := 130;
LData[1] := 131;
LData[2] := 132;
IBDataSet1.FieldByName('Data').AsBytes := LData;
//============
LStrm := IBDataSet1.CreateBlobStream(IBDataSet1.FieldByName('Data'), bmWrite);
try
  LStrm.WriteData(LData, Length(LData));
finally
  LStrm.Free;
end;

везде вылетает ошибка
arithmetic exception, numeric overflow, or string truncation

Cannot transliterate character between character sets.


Сервер IB2009. Компоненты IBX. Delphi XE3

С уважением, Vasilisk
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39716850
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

OCTETS в Interbase нету?
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39716857
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов ДенисOCTETS в Interbase нету?

Должно быть. Это очень древняя вещь.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39716865
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

попробуй

Код: sql
1.
DATA  VARCHAR(60) CHARACTER SET OCTETS
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39716868
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов ДенисOCTETS в Interbase нету?Есть. Сейчас щупаю
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39716880
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Дениспопробуй

Код: sql
1.
DATA  VARCHAR(60) CHARACTER SET OCTETS

Адекватно записать данные не удается

Код: pascal
1.
2.
 IBDataSet3.FieldByName('Data').AsBytes := LData;
  IBDataSet3.FieldByName('Data').SetData(LData);

вычисляет длину данных как
Код: pascal
1.
StrLen(PChar(Buffer))

соответственно два стоящих подряд #0#0 усекает данные. SetAsAnsiString определена как
Код: pascal
1.
2.
3.
4.
procedure TField.SetAsAnsiString(const Value: AnsiString);
begin
  SetAsString(string(Value));
end;

и теперь один #0 усекает строку.

Вызов CreateBlobStream приводит к AV
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39716884
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все, что приходит в голову - это сохранять в HEX или на клиента отдавать поле как BLOB
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39716893
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выкинуть DataSet и использовать IBSQL не предлагать?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39716896
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovВыкинуть DataSet и использовать IBSQL не предлагать?..Пока нет.

Внутренний фреймворк заточен на TDataSet
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39716925
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если отнаследоваться от TIBDataSet, переопределить InternalInitFieldDefs и на CHARSET NONE/OCTETS вернуть FieldType = ftBlob взлетит?
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39716942
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Какого типа поле создаётся в датасете ?
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39716979
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

собственно, поскольку в большинстве компонент varchar или char преобразуется в строку C с окончанием нулями, то никакие бинарные данные туда записать нельзя. OCTETS может чего и даст, но не факт.
Поэтому, бинарные данные пишутся только в блоб.
_Vasilisk_Также на это поле нужен уникальный ключ.
это ахинея, ответственно заявляю. По бинарным данным, особенно длиной 60 байт, не может быть никакого уникального ключа.
Читаем
http://www.ibase.ru/natural-keys-versus-atrificial-keys-by-tentser/
выход - доп. столбец как хэш этих 60 бинарных байт, и вот его уже можно делать уникальным.
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39717040
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvв большинстве компонент varchar или char преобразуется в строку C с окончанием нулями

Нет, так делают только очень-очень глупые компоненты, а таких всё-таки не большинство.

kdvПо бинарным данным, особенно длиной 60 байт, не может быть никакого уникального
ключа.
Да ну? 4 или 8 бинарных байт целого - уникальный ключ в порядке, 16 байт гуида -
уникальный ключ в порядке, а на 60 вдруг внезапный качественный скачок и уникальный ключ
невозможен? Ты ещё скажи, что на строках вообще уникальные ограничения невозможны...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39717097
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladКакого типа поле создаётся в датасете ?ftString (TIBStringField)
kdvвыход - доп. столбец как хэш этих 60 бинарных байт, и вот его уже можно делать уникальным.Это не выход

1. Хеш по определению не может быть уникальным
2. Хеш это те-же бинарные данные, которые нужно как-то сохранять
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39717100
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хеш (тем паче их много разных) - всё же имеет представление в виде строки.
Хотя в твоём случае особого смысла в нём нет, лучше добить обработку binary.

Data содержит корректные данные (байты) ? Строковое представление тебе,
по сути, вроде бы не нужно.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39717102
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_hvladКакого типа поле создаётся в датасете ?ftString (TIBStringField)А должно быть [var]binary. Без этого не получится.
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39717104
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамХеш (тем паче их много разных) - всё же имеет представление в виде строки.Я с тем же успехом могу данные записать в hex
Гаджимурадов РустамData содержит корректные данные (байты) ?Ты сейчас о поле? Я же говорю - обрезается до перого #0 если такой встретится
Гаджимурадов РустамСтроковое представление тебе, по сути, вроде бы не нужно.Нет
Гаджимурадов Рустамлучше добить обработку binary.В понедельник еще поковыряюсь
hvladА должно быть [var]binary.Это какой тип?
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39717107
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_> Ты сейчас о поле? Я же говорю - обрезается

Нет, конечно, о свойстве (не помню, доступно ли оно в TField).
Хотя если у тебя даже Get/SetData не пашут, то, наверное, нет.

> Это какой тип?

ftBytes, видимо.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39717116
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_hvladА должно быть [var]binary.Это какой тип?Насколько я понимаю и помню эту кухню, нужно править TIBCustomDataSet.InternalInitFieldDefs, чтобы оно создавало ftVarBytes (ftBytes)
при наличии чарсета OCTETS у поля SQL_VARYING (SQL_TEXT)
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39718271
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladНасколько я понимаю и помню эту кухню, нужно править TIBCustomDataSet.InternalInitFieldDefs, чтобы оно создавало ftVarBytes (ftBytes)
при наличии чарсета OCTETS у поля SQL_VARYING (SQL_TEXT)Не взлетело.

При подмене типа получаем картину
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
procedure TDataSet.SetFieldData(Field: TField; Buffer: TValueBuffer; NativeFormat: Boolean);
var
  StackBuf: TArray<Byte>;
begin
  if NativeFormat then
    SetFieldData(Field, Buffer)
  else
  begin
    SetLength(StackBuf, Field.DataSize);
    if Buffer <> nil then
      DataConvert(Field, Buffer, StackBuf, True);
    SetFieldData(Field, StackBuf);
  end;
end;

procedure TDataSet.DataConvert(Field: TField; Source, Dest: TValueBuffer; ToNative: Boolean);
var
  DataSize: Word;
  DateTimeRec: TDateTimeRec;
begin
  case Field.DataType of
    ..........
    ftVarBytes:
      if ToNative then
      begin
        DataSize := Length(Source);
        Move(DataSize, Dest[0], SizeOf(Word));
        Move(Source[0], Dest[SizeOf(Word)], DataSize);
      end
      else
      begin
        Move(Source[0], DataSize, SizeOf(Word));
        Move(Source[SizeOf(Word)], Dest[0], DataSize);
      end;

В начало буфера добавляется еще и длина. А потом, контрольный в голову
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
procedure TIBCustomDataSet.InternalSetFieldData(Field: TField; Buffer: TValueBuffer);
var
  Buff : TRecordBuffer;
begin
  Buff := GetActiveBuf;
  ...............
        Move(Buffer[0], Buff[PRecordData(Buff)^.rdFields[FMappedFieldPosition[Field.FieldNo - 1]].fdDataOfs],
               PRecordData(Buff)^.rdFields[FMappedFieldPosition[Field.FieldNo - 1]].fdDataSize);
        if (PRecordData(Buff)^.rdFields[FMappedFieldPosition[Field.FieldNo - 1]].fdDataType = SQL_TEXT) or
           (PRecordData(Buff)^.rdFields[FMappedFieldPosition[Field.FieldNo - 1]].fdDataType = SQL_VARYING) then
          PRecordData(Buff)^.rdFields[FMappedFieldPosition[Field.FieldNo - 1]].fdDataLength := StrLen(PChar(Buffer)) * 2;
        PRecordData(Buff)^.rdFields[FMappedFieldPosition[Field.FieldNo - 1]].fdIsNull := False;

InternalSetFieldData имела в виду мои ftVarBytes

Если тип поля в InternalInitFieldDefs вернуть как ftBlob, то на Post возникает "Internal error"
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39718278
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Код: pascal
1.
StrLen(PChar(Buffer))



ну это чепуха для бинарных данных
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39718297
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисну это чепуха для бинарных данныхЯ знаю. Но так оно есть.
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39718298
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну раз уж начал править, правь
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39718302
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_В начало буфера добавляется еще и длинаУ себя в буфере могут и фазу луны хранить, тебе-то что
_Vasilisk_InternalSetFieldData имела в виду мои ftVarBytesНу так надо её наказать научить

PS За многократное повторение PRecordData(Buff)^.rdFields[FMappedFieldPosition[Field.FieldNo - 1]] автора этого кода нужно сколько же раз проклясть канделябром...
...
Рейтинг: 0 / 0
Сохранение бинарных данных
    #39718310
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Код: pascal
1.
2.
        if (PRecordData(Buff)^.rdFields[FMappedFieldPosition[Field.FieldNo - 1]].fdDataType = SQL_TEXT) or
           (PRecordData(Buff)^.rdFields[FMappedFieldPosition[Field.FieldNo - 1]].fdDataType = SQL_VARYING) then



добавь проверку CHARSET. Как не подскажу, пока нет времени разбираться
...
Рейтинг: 0 / 0
25 сообщений из 52, страница 1 из 3
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Сохранение бинарных данных
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]