powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как записать/ прочитать динамический массив в BLOB поле
17 сообщений из 17, страница 1 из 1
Как записать/ прочитать динамический массив в BLOB поле
    #39896079
FIL23
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрых суток,

Собственно сам сабж. (я не программист, я системный администратор)

Имеется класс

Код: pascal
1.
2.
3.
4.
      MasOfObjectsOfInventory = record
      ID:integer;         
      ObjectName: string;
      end;



Имеем динамический массив
Код: pascal
1.
2.
var
masObjectsOfInventoryOnStart:array of MasOfObjectsOfInventory ;



...
тут действия с массивом, установка его размера и занесение в него данных
...

Пытаюсь записать в BLOB
Код: 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.
35.
36.
37.
38.
39.
40.
41.
insertDataInTableofBLOBField(masObjectsOfInventoryOnStart);

function insertDataInTableofBLOBField(masObjectsOfInventoryOnStart:MasOfObjectsOfInventory):BOOLEAN;

var
  per_IBQuery:TIBQuery;
  Stm: TMemoryStream;
  Len1, Len2: LongInt;
  Str1, Str2: WideString;
begin   
      // процедура для записи введеных данных
      per_IBQuery:=my_initialization_TIBQuery_insert(per_IBQuery); //инициализируем переменную TIBQuery и передаем ей параметры подключения
      per_IBQuery.Active := False;
      per_IBQuery.SQL.Clear;
      per_IBQuery.SQL.Add('insert into HISTORY_INVENTORY '
                          + '(ID_INVENTORY, '                   { ид Представителя в дереве }
                          + ' HISTORY '
                          + ')'
                          + ' values ( '
                          + ':perID_INVENTORY, '
                          + ':perHISTORY '
                          + ')');


      Stm := TMemoryStream.Create;
      try

      Stm.Write(masObjectsOfInventoryOnStart, sizeof(masObjectsOfInventoryOnStart));


      Stm.Position := 0;
      per_IBQuery.ParamByName('perHISTORY').LoadFromStream( Stm, ftBlob);
      finally
      FreeAndNil(Stm)
      end;

      if  perID_INVENTORY=0         then per_IBQuery.ParamByName('perID_INVENTORY').IsNull  else  per_IBQuery.ParamByName('perID_INVENTORY').AsInteger:=perID_INVENTORY;

      per_IBQuery.ExecSQL;
      fmConnectToBase.IBTransaction2.Commit;
      FreeAndNil(per_IBQuery); //Эквивалентно: People. Free; People := nil;




Вроде записывает все ок тут

Но вот как считать правильно?


Пытаюсь так

Код: 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.
function GetDataFromBLOB(perID:integer):MasOfObjectsOfInventory;

var
  per_IBQuery:TIBQuery;
  stm: TStream;
  Len, Len2: LongInt;
  Str, Str2: WideString;
  perParameterHistoryInventory:type_InventoryHistory;

begin
per_IBQuery:=my_initialization_TIBQuery_insert(per_IBQuery); //инициализируем переменную и передаем ей параметры
per_IBQuery.Active:=false;
per_IBQuery.SQL.Clear;
per_IBQuery.SQL.Add('select * from HISTORY_INVENTORY WHERE ID = :perID');
if  perID=0 then per_IBQuery.ParamByName('perID').IsNull else  per_IBQuery.ParamByName('perID').AsInteger:=perID;
per_IBQuery.Active:=true;
per_IBQuery.Last;


stm := per_IBQuery.CreateBlobStream( per_IBQuery.FieldByName('HISTORY'), bmRead);
   try 
   Stm.Position:=0;

   Stm.Read(masObjectsOfInventoryOnStart,                      sizeof(masObjectsOfInventoryOnStart));

   result:=masObjectsOfInventoryOnStart;
   finally
      FreeAndNil(Stm);
   end;

end;



И получаю ошибку вида:

---------------------------
Debugger Exception Notification
---------------------------
Project alladmin.exe raised exception class EAccessViolation with message 'Access violation at address 00405864 in module 'alladmin.exe'. Read of address 01DBE13C'. Process stopped. Use Step or Run to continue.
---------------------------
OK Help
---------------------------

Я так понимаю надо задать размер массива , а как это сделать? это ж надо как то вычислить размер , я не совсем догоняю
...
Рейтинг: 0 / 0
Как записать/ прочитать динамический массив в BLOB поле
    #39896091
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FIL23,

1. используй TIBSQL, зачем тебе эта TIBQuery.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
var
  fQ : TIBSQL;
  fMS : TMemoryStream;
  faI : array of Integer;
begin
  fMS := TMemoryStream.Create;
...
  fQ.FieldByName('123').SaveToStream(fMS);
  SetLength(faI, fMS.Size div sizeOf(Integer));
  if fMS.Size > 0 then
    CopyMemory(@faI[0], fMS.Memory, Length(faI) * SizeOf(Integer));



2. Хер тебе, а не запись массива в блоб
Код: pascal
1.
2.
3.
4.
5.
6.
7.
type
      MasOfObjectsOfInventory = record
      ID:integer;         
      ObjectName: string;
      end;
var
masObjectsOfInventoryOnStart:array of MasOfObjectsOfInventory ;


Строки хранятся "совсем в другом месте", а не в самой записи. В самой записи - только указатель на строку.
Используй паскалевские строки, с указанием их размеров. А не дельфийские.
...
Рейтинг: 0 / 0
Как записать/ прочитать динамический массив в BLOB поле
    #39896100
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FIL23
Но вот как считать правильно?

п.1 Сначала нужно записать количество записей, а перед чтением прочитать это количество.
Плюс, либо
ёёёёё
Используй паскалевские строки, с указанием их размеров. А не дельфийские.

Либо вручную писать каждый record, а строку писать аналогично п.1 - сначала длину строки, затем её содержимое.
...
Рейтинг: 0 / 0
Как записать/ прочитать динамический массив в BLOB поле
    #39896104
FIL23
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
про TIBSQL кто с чем привык работать. я тут уже куча строк написал на TIBQuery, в будущих проектах попробую посмотреть в сторону TIBSQL



Про string. Что там не так , можно поподробней?

т.е. я должен писать string[255] ?
...
Рейтинг: 0 / 0
Как записать/ прочитать динамический массив в BLOB поле
    #39896107
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FIL23
Про string. Что там не так , можно поподробней?

Современная строка это ссылка на кусок памяти, где символы этой строки.
FIL23
т.е. я должен писать string[255] ?

Типа того. Чем меньше, тем лучше для базы.
...
Рейтинг: 0 / 0
Как записать/ прочитать динамический массив в BLOB поле
    #39896114
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FIL23
Про string. Что там не так , можно поподробней?
Расположение в памяти там не так:
...
Рейтинг: 0 / 0
Как записать/ прочитать динамический массив в BLOB поле
    #39896121
FIL23
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хорошо,

у меня есть написанная та же функция с записями стринг полей, оставлю тут , мало ли кому пригодится тут добавляется и числа и строки

Код: 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.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
function insertDataInHistory_InventoryTable(perID_INVENTORY:integer; perParameterHistoryInventory:type_InventoryHistory):BOOLEAN;

    procedure WriteStringToStream(perStm:TMemoryStream;perStr:WideString);
      var
        perLen:LongInt;
      begin
      perLen := Length(perStr);
      perStm.Write(perLen, SizeOf(perLen));
      if perLen > 0 then
        perStm.Write(perStr[1], Length(perStr) * SizeOf(perStr[1]));
      end;

var
  per_IBQuery:TIBQuery;
  Stm: TMemoryStream;
  Len1, Len2: LongInt;
  Str1, Str2: WideString;
begin   
      // процедура для записи введеных данных
      per_IBQuery:=my_initialization_TIBQuery_insert(per_IBQuery); //инициализируем переменную и передаем ей параметры
      per_IBQuery.Active := False;
      per_IBQuery.SQL.Clear;
      per_IBQuery.SQL.Add('insert into HISTORY_INVENTORY '
                          + '(ID_INVENTORY, '                   { ид Представителя в дереве }
                          + ' HISTORY '
                          + ')'
                          + ' values ( '
                          + ':perID_INVENTORY, '
                          + ':perHISTORY '
                          + ')');


      Stm := TMemoryStream.Create;
      try
      Stm.Write(perParameterHistoryInventory.UserID_,     sizeof(perParameterHistoryInventory.UserID_) );//кто  //первый параметр что записываем , второй параметр сколько записываем, потом указатель сам Cдвигается


      WriteStringToStream(Stm, perParameterHistoryInventory.Path_before);       //путь до объекта до
   

      Stm.Position := 0;
      per_IBQuery.ParamByName('perHISTORY').LoadFromStream( Stm, ftBlob);
      finally
      FreeAndNil(Stm)
      end;

      if  perID_INVENTORY=0         then per_IBQuery.ParamByName('perID_INVENTORY').IsNull  else  per_IBQuery.ParamByName('perID_INVENTORY').AsInteger:=perID_INVENTORY;

      per_IBQuery.ExecSQL;
      fmConnectToBase.IBTransaction2.Commit;
      FreeAndNil(per_IBQuery); //Эквивалентно: People. Free; People := nil;
end;
//******************************************************************************
//******************************************************************************




т.е. ваш совет динамический массив заганять в цикл и записывать уже построчно в BLOB?
...
Рейтинг: 0 / 0
Как записать/ прочитать динамический массив в BLOB поле
    #39896126
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FIL23
у меня есть написанная та же функция с записями стринг полей


Код: pascal
1.
поле.AsString := 'Колбаса'


- не?
...
Рейтинг: 0 / 0
Как записать/ прочитать динамический массив в BLOB поле
    #39896174
FIL23
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Как записать/ прочитать динамический массив в BLOB поле
    #39896192
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FIL23,

в чем вопрос?
...
Рейтинг: 0 / 0
Как записать/ прочитать динамический массив в BLOB поле
    #39896229
FIL23
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну там показано как с record поступать.

А с массивом как?

В цикл его разворачивать ?
...
Рейтинг: 0 / 0
Как записать/ прочитать динамический массив в BLOB поле
    #39896232
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FIL23,

при чем тут "в цикл".

Хоть одну запись. Если у тебя структура содержит ссылку - ты должен отработать этот момент. Если, конечно, тебя интересует, на что эта ссылка указывает.
...
Рейтинг: 0 / 0
Как записать/ прочитать динамический массив в BLOB поле
    #39896417
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FIL23
А с массивом как?
В цикл его разворачивать ?

Если там есть ссылочные типы (строки, динамические массивы и т.п.) или записи с ними, то сначала записать количество элементов, потом элементы в цикле, при этом ссылочные типы сохраняются отдельно каждый.

Если там простые типы (или записи из простых типов), то сначала количество элементов (опционально, для удобства чтения), потом весь массив одним куском.
...
Рейтинг: 0 / 0
Как записать/ прочитать динамический массив в BLOB поле
    #39896477
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
TMasOfObjectsOfInventory = record
  ID: integer;         
  ObjectName: string;
  procedure ReadFromStream(AStream: TStream);
  procedure WriteToStream(AStream: TStream);
end

procedure TMasOfObjectsOfInventory.ReadFromStream(AStream: TStream);
var
  LLen: Integer;
begin
  AStream.WriteBuffer(ID, SizeOf(ID));
  LLen := Length(ObjectName);
  AStream.WriteBuffer(LLen, SizeOf(LLen));
  AStream.WriteBuffer(Pointer(ObjectName)^, LLen * SizeOf(Char));
end;

procedure TMasOfObjectsOfInventory.WriteToStream(AStream: TStream);
var
  LLen: Integer;
begin
  AStream.ReadBuffer(ID, SizeOf(ID));
  AStream.ReadBuffer(LLen, SizeOf(LLen));
  SetLength(ObjectName, LLen);
  AStream.ReadBuffer(Pointer(ObjectName)^, LLen * SizeOf(Char));
end;

function insertDataInTableofBLOBField(masObjectsOfInventoryOnStart:MasOfObjectsOfInventory):BOOLEAN;

var
  per_IBQuery:TIBQuery;
  Stm: TMemoryStream;
  LLen: Integer;
  Li: Integer;
begin   
  per_IBQuery:=my_initialization_TIBQuery_insert(per_IBQuery);
  try
    per_IBQuery.Transaction.Active := True;
    try
      per_IBQuery.SQL.Text := 'insert into HISTORY_INVENTORY '
                          + '(ID_INVENTORY, '                   { ид Представителя в дереве }
                          + ' HISTORY '
                          + ')'
                          + ' values ( '
                          + ':perID_INVENTORY, '
                          + ':perHISTORY '
                          + ')';

      Stm := TMemoryStream.Create;
      try
        LLen := Length(masObjectsOfInventoryOnStart);
        Strm.WriteBuffer(LLen, SizeOf(LLen));
        for Li := 0 to LLen - 1 do
          masObjectsOfInventoryOnStart[Li].WriteToStream(Strm);

        Stm.Position := 0;
        per_IBQuery.ParamByName('perHISTORY').LoadFromStream(Stm, ftBlob);
      finally
        Strm.Free;
      end;

      if  perID_INVENTORY=0  then
        per_IBQuery.ParamByName('perID_INVENTORY').>>Clear<<
      else
        per_IBQuery.ParamByName('perID_INVENTORY').AsInteger:=perID_INVENTORY;

      per_IBQuery.ExecSQL;
    finally
      per_IBQuery.Transaction.Commit;
    end;
  finally
    per_IBQuery.Free;
  end;
end;

function GetDataFromBLOB(perID:integer): MasOfObjectsOfInventory;
var
  per_IBQuery:TIBQuery;
  stm: TStream;
  LLen: Integer;
  Li: Integer;
begin
  per_IBQuery:=my_initialization_TIBQuery_insert(per_IBQuery); //инициализируем переменную и передаем ей параметры
  try
    per_IBQuery.SQL.Text := 'select * from HISTORY_INVENTORY WHERE ID = :perID';
    if  perID=0 then
      per_IBQuery.ParamByName('perID').Clear
    else
      per_IBQuery.ParamByName('perID').AsInteger:=perID;
    per_IBQuery.Active:=true;
    stm := per_IBQuery.CreateBlobStream( per_IBQuery.FieldByName('HISTORY'), bmRead);
    try 
      Stm.ReadBuffer(LLen, SizeOf(LLen));
      SetLength(Result, LLen);
      for Li := 0 to LLen - 1 do
        Result[Li].ReadFromStream(Strm);
     finally
       Stm.Free;
     end;
  finally
    per_IBQuery.Free;
  end;
end;

А если при сохранении использовать TIBSQL, то можно обойтись без ненужного копирования
FIL23
Код: pascal
1.
per_IBQuery.ParamByName('perHISTORY').LoadFromStream( Stm, ftBlob);

...
Рейтинг: 0 / 0
Как записать/ прочитать динамический массив в BLOB поле
    #39896565
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Зачёт!

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
procedure TMasOfObjectsOfInventory.ReadFromStream(AStream: TStream);
var
  LLen: Integer;
begin
  AStream.WriteBuffer(ID, SizeOf(ID));
  LLen := Length(ObjectName);
  AStream.WriteBuffer(LLen, SizeOf(LLen));
  AStream.WriteBuffer(Pointer(ObjectName)^, LLen * SizeOf(Char));
end;

procedure TMasOfObjectsOfInventory.WriteToStream(AStream: TStream);
var
  LLen: Integer;
begin
  AStream.ReadBuffer(ID, SizeOf(ID));
  AStream.ReadBuffer(LLen, SizeOf(LLen));
  SetLength(ObjectName, LLen);
  AStream.ReadBuffer(Pointer(ObjectName)^, LLen * SizeOf(Char));
end;
...
Рейтинг: 0 / 0
Как записать/ прочитать динамический массив в BLOB поле
    #39896600
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,

А потом этот код будет отсюда скопипащщен и включен в новый функционал Delphi 10.3.4.
...
Рейтинг: 0 / 0
Как записать/ прочитать динамический массив в BLOB поле
    #39896610
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp
Зачёт!


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


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