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

У меня в проекте есть модуль (назовем его PkBase), в котором обрабатываются вызовы хранимых процедур из БД Oracle. В рабочей форме есть переменная этого класса. В самом PkBase есть процедура обращения в БД одним из возвращаемых параметров которой есть переменная типа TOraLob. Выполняю её, ошибок нет. Полученный блоб сохраняю в файл. Но когда приходит очередь закрывать форму, то вываливается ошибка
...
Рейтинг: 0 / 0
01.11.2018, 19:00
    #39726798
Леонов Юрий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Закрытие формы и TOraLob
Я просто нигде не найду пример с возвратом блоба из хп. Что я делаю не правильно?
...
Рейтинг: 0 / 0
01.11.2018, 19:10
    #39726804
Квейд
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Закрытие формы и TOraLob
Как пробовал?
...
Рейтинг: 0 / 0
02.11.2018, 10:14
    #39727014
Леонов Юрий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Закрытие формы и TOraLob
Вот класс для общения с БД
Код: 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
02.11.2018, 11:04
    #39727060
ma1tus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Закрытие формы и TOraLob
Имхо, здесь уничтожается Леонов Юрий
Код: 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
02.11.2018, 11:30
    #39727100
Леонов Юрий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Закрытие формы и TOraLob
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
02.11.2018, 11:45
    #39727114
Квейд
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Закрытие формы и TOraLob
Леонов Юрий
Код: pascal
1.
2.
    if Assigned(LSaveDialog) then
      FreeAndNil(LSaveDialog);


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


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

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


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

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



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

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

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

Я наверное чего-то недопонял... Я создаю LLob, записываю процедурой в него значение, сохраняю из этого же LLob в файл и потом этот же LLob я уничтожаю... Что-то я запутался. Можете привести пример, как должно быть?
...
Рейтинг: 0 / 0
02.11.2018, 13:14
    #39727195
goldmi45
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Закрытие формы и TOraLob
Код: 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
02.11.2018, 13:20
    #39727200
Леонов Юрий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Закрытие формы и TOraLob
goldmi45,

как правильно тогда сделать? Я же не могу не создавая экземпляр что-то в него писать
...
Рейтинг: 0 / 0
02.11.2018, 13:23
    #39727203
goldmi45
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Закрытие формы и TOraLob
Леонов Юрий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
02.11.2018, 13:25
    #39727204
goldmi45
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Закрытие формы и TOraLob
Леонов Юрий,

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

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

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

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

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

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

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

Таки да, закомментил удаление LLob и все наладилось. Не учел момент, что переопределяется адрес переменной.
Спасибо, растолковали))
...
Рейтинг: 0 / 0
05.11.2018, 16:24
    #39728136
Леонов Юрий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Закрытие формы и TOraLob
Финальный вариант вызова выглядит так, если кому будет нужно:
Код: 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
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Закрытие формы и TOraLob / 21 сообщений из 21, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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