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

У меня в проекте есть модуль (назовем его PkBase), в котором обрабатываются вызовы хранимых процедур из БД Oracle. В рабочей форме есть переменная этого класса. В самом PkBase есть процедура обращения в БД одним из возвращаемых параметров которой есть переменная типа TOraLob. Выполняю её, ошибок нет. Полученный блоб сохраняю в файл. Но когда приходит очередь закрывать форму, то вываливается ошибка
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39726798
Леонов Юрий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я просто нигде не найду пример с возвратом блоба из хп. Что я делаю не правильно?
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39726804
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как пробовал?
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39727014
Леонов Юрий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот класс для общения с БД
Код: 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.
unit PkBase;

interface

uses Classes, SysUtils, Ora, OraPackage, System.Variants, OraUtils,
  System.Generics.Collections, Data.DB, OraClasses;

TPkBase = class(TCustomOraPackage)
  private
    FSession: TOraSession;
    procedure GetStoreProc;
    function GetSession: TOraSession;
    procedure SetSession(AValue: TOraSession);
  protected
    StoredProc: TOraStoredProc;
  published
    property Session: TOraSession read GetSession write SetSession;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    //òóò èäóò âûçîâû ïðîöåäóð è ôóíêöèé
   ...
   procedure InsertBlob(const PFileName: string; const PFKey: Double; const PBlob: TOraLob);
   ...
   procedure GetBlob(const PFileKey: Double; out PFileName: string; out PBlob: TOraLob);
   ...
  end;

implementation

constructor TPkBase.Create(AOwner: TComponent);
begin
  inherited;
  StoredProc := TOraStoredProc.Create(nil);
end;

destructor TPkBase.Destroy;
begin
  if Assigned(StoredProc) then
    FreeAndNil(StoredProc);
  inherited;
end;

procedure TPkBase.GetStoreProc;
begin
  StoredProc.Session := Session;
  StoredProc.StoredProcName := '';
  StoredProc.Prepared;
end;

procedure TPkBase.InsertBlob(const PFileName: string; const PFKey: Double; const PBlob: TOraLob);
begin
  GetStoreProc;
  StoredProc.StoredProcName := '<PKG>.INSERT_BLOB';
  StoredProc.Prepare;
  StoredProc.ParamByName('P_FULLNAME').AsString := PFileName;
  StoredProc.ParamByName('P_FKEY').AsFloat := PFKey;
  StoredProc.ParamByName('P_BLOB').AsOraBlob := PBlob;
  StoredProc.Execute;
end;

procedure TPkBase.GetBlob(const PFileKey: Double; out PFileName: string; out PBlob: TOraLob);
begin
  GetStoreProc;
  StoredProc.StoredProcName := '<PKG>.GET_BLOB';
  StoredProc.Prepare;
  StoredProc.ParamByName('P_FKEY').AsFloat := PFileKey;
  StoredProc.Execute;
  PFileName := StoredProc.ParamByName('P_FULLNAME').AsString;
  PBlob := StoredProc.ParamByName('P_BLOB').AsOraBlob;
  //StoredProc.ParamByName('P_BLOB').AsOraBlob.FreeBlob;
end;



Теперь вызов

Код: 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.
unit FileReestr;

interface

uses
  ...
  PkBase;

type
  TfrmFileReestr = class(TfrmMDIForm)  //родитель - мой класс, обычная форма с FormStyle=fsMDIChild
    ...
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    ...
    procedure actUnloadFilesExecute(Sender: TObject);
  private
    FPkBase: TPkBase;

var
  frmFileReestr: TfrmFileReestr;

implementation

{$R *.DFM}

procedure TfrmFileReestr.FormCreate(Sender: TObject);
begin
  inherited;
  ...
  FPkBase := TPkMop.Create(nil);
  FPkBase.Session := DefSession;
end;

procedure TfrmFileReestr.FormDestroy(Sender: TObject);
begin
  if Assigned(FPkBase) then
    FreeAndNil(FPkBase);
  inherited;
end;

procedure TfrmFileReestr.actUnloadFilesExecute(Sender: TObject);
Var
  LLob: TOraLob;
  LFileName, LSaveDir: string;
  LSaveDialog: TSaveDialog;
begin
  try
    LSaveDialog := TSaveDialog.Create(nil);
    try
      LSaveDir := ExtractFileDir(Application.ExeName) + '\';
      LLob := TOraLob.Create(DefSession.OCISvcCtx);
      LLob.AllocLob;
      LLob.CreateTemporary(ltBlob);
      FPkBase.GetBlob(FFileKey, LFileName, LLob);
      LSaveDialog.InitialDir := LSaveDir;
      LSaveDialog.FileName := LFileName;
      LSaveDialog.Filter := '*|*';
      if LSaveDialog.Execute then
        LLob.SaveToFile(LSaveDialog.FileName);
      MessageDlg('Файл успішно вивантажено!', mtInformation, [mbOK], 0);
    except
      on E: Exception do
      begin
        Application.ShowException(E);
      end;
    end;
  finally
    if Assigned(LSaveDialog) then
      FreeAndNil(LSaveDialog);
    if Assigned(LLob) then
      LLob.Free;
  end;
end;


Вызов отрабатывает нормально, но при закрытии формы frmFileReestr вылетает ошибка. После нее все нормально, приложение продолжает работать.

Среда Embarcadero Berlin, компоненты ODAC, база Oracle 11.2.0.4.0
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39727060
ma1tus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имхо, здесь уничтожается Леонов Юрий
Код: pascal
1.
LLob.Free;

не этот объектЛеонов Юрий
Код: pascal
1.
2.
3.
procedure TfrmFileReestr.actUnloadFilesExecute(Sender: TObject);
Var
  LLob: TOraLob;

Не создавать, а просто возвращать TOraLob из TPkBase.GetBlob - не?

...Леонов Юрий
Код: pascal
1.
LLob.AllocLob;

CreateTemporary сам это делает...
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39727100
Леонов Юрий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ma1tusИмхо, здесь уничтожается Леонов Юрий
Код: pascal
1.
LLob.Free;

не этот объект
А какой должен уничтожаться?

ma1tusНе создавать, а просто возвращать TOraLob из TPkBase.GetBlob - не?

У меня 2 параметра функцией возвращается, имя файла и собственно блоб, оба нужны в процедуре.

Ошибка вылетает тут

Код: pascal
1.
2.
3.
4.
5.
6.
procedure TfrmFileReestr.FormDestroy(Sender: TObject);
begin
  if Assigned(FPkBase) then
    FreeAndNil(FPkBase); //вот тут вылетает
  inherited;
end;
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39727114
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Леонов Юрий
Код: pascal
1.
2.
    if Assigned(LSaveDialog) then
      FreeAndNil(LSaveDialog);


Выделенное лишнее
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39727131
ma1tus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Леонов ЮрийА какой должен уничтожаться?вот этот...
Код: pascal
1.
LLob := TOraLob.Create(DefSession.OCISvcCtx);


Процедура TPkBase.GetBlob, через параметр
Код: pascal
1.
out PBlob: TOraLob

записывает в LLob свой объект, а ваш, ручками созданный по этому адресу - утекает...
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39727158
Леонов Юрий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КвейдЛеонов Юрий
Код: pascal
1.
2.
    if Assigned(LSaveDialog) then
      FreeAndNil(LSaveDialog);


Выделенное лишнее

Это не существенно, привычка проверять
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39727162
Леонов Юрий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ma1tusЛеонов ЮрийА какой должен уничтожаться?вот этот...
Код: pascal
1.
LLob := TOraLob.Create(DefSession.OCISvcCtx);



А я какой уничтожаю?

ma1tusПроцедура TPkBase.GetBlob, через параметр
Код: pascal
1.
out PBlob: TOraLob

записывает в LLob свой объект, а ваш, ручками созданный по этому адресу - утекает...

Я наверное чего-то недопонял... Я создаю LLob, записываю процедурой в него значение, сохраняю из этого же LLob в файл и потом этот же LLob я уничтожаю... Что-то я запутался. Можете привести пример, как должно быть?
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39727195
goldmi45
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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.
procedure TfrmFileReestr.actUnloadFilesExecute(Sender: TObject);
Var
  LLob: TOraLob;
  LFileName, LSaveDir: string;
  LSaveDialog: TSaveDialog;
begin
  try
    LSaveDialog := TSaveDialog.Create(nil);
    try
      LSaveDir := ExtractFileDir(Application.ExeName) + '\';
      LLob := TOraLob.Create(DefSession.OCISvcCtx); /// Создали свой LLob
      LLob.AllocLob;
      LLob.CreateTemporary(ltBlob);
      FPkBase.GetBlob(FFileKey, LFileName, LLob); /// Перезаписали LLob (стал новый LLob, а старый потеряли)
    ....
    except
      on E: Exception do
      begin
        Application.ShowException(E);
      end;
    end;
  finally
    if Assigned(LSaveDialog) then
      FreeAndNil(LSaveDialog);
    if Assigned(LLob) then
      LLob.Free; /// Уничтожили тот, который получили из GetBlob, а который создавали, утёк
  end;
end;
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39727200
Леонов Юрий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
goldmi45,

как правильно тогда сделать? Я же не могу не создавая экземпляр что-то в него писать
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39727203
goldmi45
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Леонов Юрийgoldmi45,

как правильно тогда сделать? Я же не могу не создавая экземпляр что-то в него писать
Почему? Разве такой код не работает:
Код: 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.
Var
  LLob: TOraLob;
  LFileName, LSaveDir: string;
  LSaveDialog: TSaveDialog;
begin
  try
    LSaveDialog := TSaveDialog.Create(nil);
    try
      LSaveDir := ExtractFileDir(Application.ExeName) + '\';
      FPkBase.GetBlob(FFileKey, LFileName, LLob);
      LSaveDialog.InitialDir := LSaveDir;
      LSaveDialog.FileName := LFileName;
      LSaveDialog.Filter := '*|*';
      if LSaveDialog.Execute then
        LLob.SaveToFile(LSaveDialog.FileName);
      MessageDlg('Файл успішно вивантажено!', mtInformation, [mbOK], 0);
    except
      on E: Exception do
      begin
        Application.ShowException(E);
      end;
    end;
  finally
    if Assigned(LSaveDialog) then
      FreeAndNil(LSaveDialog);
    if Assigned(LLob) then
      LLob.Free;
  end;
end;
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39727204
goldmi45
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Леонов Юрий,

out-параметр и var-параметр вообще-то отличаются.
У вас out
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39727212
Леонов Юрий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
goldmi45,

да в этом коде все устраивает, не устраивает только ошибка, которая вылетает по закрытии формы
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39727216
Леонов Юрий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
goldmi45Леонов Юрий,

out-параметр и var-параметр вообще-то отличаются.
У вас out

Разницы никакой для этого случая
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39727218
goldmi45
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Леонов Юрий,

хм, вроде как не нужно даже уничтожать экземпляр LLob: TOraLob в процедуре TfrmFileReestr.actUnloadFilesExecute. Он уничтожится вместе с экземпляром StoredProc
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39727222
Леонов Юрий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
goldmi45Леонов Юрий,

хм, вроде как не нужно даже уничтожать экземпляр LLob: TOraLob в процедуре TfrmFileReestr.actUnloadFilesExecute. Он уничтожится вместе с экземпляром StoredProc

Интересно, а если я повторно нажму кнопку, что тогда будет? Мусорная куча, пока я не закрою форму?
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39727223
goldmi45
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Леонов ЮрийИнтересно, а если я повторно нажму кнопку, что тогда будет? Мусорная куча, пока я не закрою форму?
Вы освобождаете не свою переменную. В этом и есть ошибка. Ну а почему не попробовать не освобождать? Вы же параметры у StoredProc тоже не освобождаете.
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39727235
Леонов Юрий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
goldmi45Леонов ЮрийИнтересно, а если я повторно нажму кнопку, что тогда будет? Мусорная куча, пока я не закрою форму?
Вы освобождаете не свою переменную. В этом и есть ошибка. Ну а почему не попробовать не освобождать? Вы же параметры у StoredProc тоже не освобождаете.

Таки да, закомментил удаление LLob и все наладилось. Не учел момент, что переопределяется адрес переменной.
Спасибо, растолковали))
...
Рейтинг: 0 / 0
Закрытие формы и TOraLob
    #39728136
Леонов Юрий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Финальный вариант вызова выглядит так, если кому будет нужно:
Код: 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.
procedure TfrmFileReestr.actUnloadFilesExecute(Sender: TObject);
Var
  LLob: TOraLob;
  LFileName, LSaveDir: string;
  LSaveDialog: TSaveDialog;
begin
  try
    LSaveDialog := TSaveDialog.Create(nil);
    try
      LSaveDir := ExtractFileDir(Application.ExeName) + '\';
      FPkBase.GetBlob(FFileKey, LFileName, LLob);
      LSaveDialog.InitialDir := LSaveDir;
      LSaveDialog.FileName := LFileName;
      LSaveDialog.Filter := '*|*';
      if LSaveDialog.Execute then
        LLob.SaveToFile(LSaveDialog.FileName);
      MessageDlg('Файл успішно вивантажено!', mtInformation, [mbOK], 0);
    except
      on E: Exception do
      begin
        Application.ShowException(E);
      end;
    end;
  finally
    if Assigned(LSaveDialog) then
      FreeAndNil(LSaveDialog);
  end;
end;


Получается, что создавать переменную типа и уничтожать не надо.
Огромная благодарность goldmi45!
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Закрытие формы и TOraLob
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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