Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Сохранение бинарных данных / 25 сообщений из 52, страница 1 из 3
12.10.2018, 18:09
    #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
12.10.2018, 18:11
    #39716850
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение бинарных данных
_Vasilisk_,

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

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

попробуй

Код: sql
1.
DATA  VARCHAR(60) CHARACTER SET OCTETS
...
Рейтинг: 0 / 0
12.10.2018, 18:43
    #39716868
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение бинарных данных
Симонов ДенисOCTETS в Interbase нету?Есть. Сейчас щупаю
...
Рейтинг: 0 / 0
12.10.2018, 19:29
    #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
12.10.2018, 19:39
    #39716884
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение бинарных данных
Все, что приходит в голову - это сохранять в HEX или на клиента отдавать поле как BLOB
...
Рейтинг: 0 / 0
12.10.2018, 20:00
    #39716893
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение бинарных данных
Выкинуть DataSet и использовать IBSQL не предлагать?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
12.10.2018, 20:05
    #39716896
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение бинарных данных
Dimitry SibiryakovВыкинуть DataSet и использовать IBSQL не предлагать?..Пока нет.

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

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

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

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

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

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

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

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

ftBytes, видимо.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
13.10.2018, 19:01
    #39717116
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение бинарных данных
_Vasilisk_hvladА должно быть [var]binary.Это какой тип?Насколько я понимаю и помню эту кухню, нужно править TIBCustomDataSet.InternalInitFieldDefs, чтобы оно создавало ftVarBytes (ftBytes)
при наличии чарсета OCTETS у поля SQL_VARYING (SQL_TEXT)
...
Рейтинг: 0 / 0
16.10.2018, 16:39
    #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
16.10.2018, 16:46
    #39718278
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сохранение бинарных данных
_Vasilisk_,

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



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

PS За многократное повторение PRecordData(Buff)^.rdFields[FMappedFieldPosition[Field.FieldNo - 1]] автора этого кода нужно сколько же раз проклясть канделябром...
...
Рейтинг: 0 / 0
16.10.2018, 17:16
    #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
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Сохранение бинарных данных / 25 сообщений из 52, страница 1 из 3
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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