Работа с NestedTable

Леонов Юрий
Дата: 28.10.2019 10:49:42
Добрый день всем гуру!

Есть такая проблема. Нужно с клиента Delphi (Embarcadero 10.1 Berlin) передать в БД (Oracle 18c) через компоненты ODAC (версия 10.3.9) таблицу с данными.
Покопавшись на просторах сети решил использовать компонент TOraNestedTable.

На сервере создал два типа:
CREATE OR REPLACE TYPE REE_REC as object
(
--тут 45 полей, не буду все перечислять
);

CREATE OR REPLACE TYPE REE_TAB AS TABLE OF REE_REC


Первый тип полностью соответствует структуре таблицы CLREE, в которую нужно будет вносить передаваемые данные.

Данные заношу так:
procedure TfrmCreateLoadFiles.UploadFile;
var
  LNestTable: TOraNestedTable;
begin
  --
  try
      LNestTable := TOraNestedTable.Create(nil);
      LNestTable.Table := TOraNestTable.Create
        (TOraType.Create(DefSession.OCISvcCtx, 'REE_TAB'));
      LNestTable.Open;
      --
      LNestTable.Append;
      LNestTable.FieldByName('FKEY').Value := FCurFileKey;
      LNestTable.FieldByName('LINE_N').Value := LLineN;
      LInd := 0;
      while Pos(chr(9), LText) > 0 do
      begin
        LVal := Copy(LText, 1, Pos(chr(9), LText) - 1);
        LNestTable.FieldByName(FRealColumnNames[LInd]).Value := Trim(LVal);
        Inc(LInd);
        Delete(LText, 1, Pos(chr(9), LText));
      end;
      LNestTable.FieldByName('F_PR').Value := '-';
      LNestTable.FieldByName('FIL').Value := FFileType;
      LNestTable.Post; //вот тут при фиксации значения всех полей записи превращаются в Null
      --
      NewImportFile_1061(LNestTable);
      --
    finally
      FreeAndNil(LNestTable);
    end;
--


Суть проблемы в том, что при вызове LNestTable.Post значения всех столбцов превращается в Null.
После LNestTable.Append ставил LNestTable.Edit, но сути это не поменяло.

Посему вопрос: как мне записать данные в LNestTable?
wadman
Дата: 28.10.2019 11:35:49
Nested table is a dataset component that encapsulates a database table that is nested as a field within another table. Use TOraNestedTable to access data contained in a nested dataset. A nested table provides much of the functionality of a table component, with the difference that the data it accesses is stored in a nested table.

Даже гугло перевод и то говорит, что компонент не подходит для этого:

Вложенная таблица - это компонент набора данных, который инкапсулирует таблицу базы данных, которая вложена как поле в другую таблицу. Используйте TOraNestedTable для доступа к данным, содержащимся во вложенном наборе данных. Вложенная таблица обеспечивает большую часть функциональности компонента таблицы, с той разницей, что данные, к которым она обращается, хранятся во вложенной таблице.
wadman
Дата: 28.10.2019 11:36:40
И по мелочи: Append и Post должны быть внутри цикла, а не за его пределами. Но ошибка тут не в этом.
Квейд
Дата: 28.10.2019 11:37:50
еще по мелочи
      LNestTable := TOraNestedTable.Create(nil);
должно быть ДО

  try
а не после
Леонов Юрий
Дата: 28.10.2019 11:57:43
wadman
И по мелочи: Append и Post должны быть внутри цикла, а не за его пределами. Но ошибка тут не в этом.


Они и так внутри
Леонов Юрий
Дата: 28.10.2019 12:04:10
Если копать глубже, то мне надо из текстового файла перенести данные в таблицу.
Логичнее всего было использовать TOraLoader. Для примера я его и использовал.Работал шустро, 43 ГБ залил всего за 2.5 часа.
Но проблема в том, что я не могу дать пользователю права на запись непосредственно в таблицу. Вот и приходится извращаться.
Как вариант хотел передать таблицей как параметр процедуры, благо TOraStoredProc позволяет это.
А так как параметр должен быть TOraNestTable, то и возникла мысль использовать TOraNestedTable
wadman
Дата: 28.10.2019 12:04:43
Леонов Юрий
wadman
И по мелочи: Append и Post должны быть внутри цикла, а не за его пределами. Но ошибка тут не в этом.


Они и так внутри

Я увидел в приведенном коде иное.
wadman
Дата: 28.10.2019 12:06:03
Леонов Юрий
Но проблема в том, что я не могу дать пользователю права на запись непосредственно в таблицу. Вот и приходится извращаться.

Есть еще один способ: залить во временную таблицу (без индексов заливка будет еще быстрее) и затем дернуть оракловую процедуру, которая из временной раскидает записи как угодно.
Леонов Юрий
Дата: 28.10.2019 13:19:51
wadman
Есть еще один способ: залить во временную таблицу (без индексов заливка будет еще быстрее) и затем дернуть оракловую процедуру, которая из временной раскидает записи как угодно.

Эта мысль была реализована, но опять таки всё упирается в права доступа.
Создавать заранее таблицу нельзя, потому как потом придется бороться с параллельной заливкой.
Если создавать по ходу выполнения закачки, то как выдать права на созданную таблицу от владельца?
Леонов Юрий
Дата: 28.10.2019 13:21:53
wadman
Я увидел в приведенном коде иное.


Интересно, что именно? Между Append и Post есть только цикл, в котором по полям ОДНОЙ ЗАПИСИ разносятся данные.