Повторная инициализация переменной / записи в PL / SQL во время цикла - PullRequest
0 голосов
/ 17 октября 2011

Чтобы создать анализатор PL / SQL для процесса ETL, в котором данные в основном кодируются позиционно, мне нужно построчно читать файл и добавлять записи в оперативную память (package- ) в текущую запись или в новую запись.

Позвольте мне кратко объяснить сценарий и правила грамматики: мне нужно проанализировать сообщения банковского выравнивания, которые имеют общедоступный стандартный формат (не могу найти документацию на английском языке, только это и другие итальянские документы, в то время как это должен быть стандарт для всего ЕС). Во всяком случае, здесь объясняются некоторые правила:

  • Каждая запись имеет длину 120 символов в файле
  • Каждый файл начинается с записи "AL" (ALignment)
  • Каждый файл заканчивается записью "EF" (End of File)
  • Каждое сообщение выравнивания начинается с записи «12» и заканчивается записью «70»
  • В зависимости от типа записи «12» сообщение может состоять из различных комбинаций других записей, таких как «30» и «40», «50», «45», «50» и «45» "50"

Пример (структурированный):

AL record
    12 record
        45 record
    70 record
    12 record
        45 record
        50 record
    70 record
EF record

Я уже объявил MESSAGE PL / SQL-таблицу CHAR(120), которая будет инкапсулировать записи между 12 и 70 (включительно), которые будут обработаны на более позднем этапе. Теперь у меня есть проблема с зацикливанием, которую я мог бы легко решить в Java.

Как я могу повторно инициализировать переменную в PL / SQL? Вот пример псевдо-Java того, что мне нужно сделать

String line;
List<String> alignment_message;
List<AlignmentMessage> table;
while (line = readline()) {
    if (line.substring(1,2)=="12") //Begin of message 
        alignment_message = new MESSAGE(); //******HOW DO I DO THIS????
    alignment_message.add(line); //Don't care about NPE ;-)

    if (line.substring(1,2)=="70") //End of message
        table.add(alignment_message);
}

В настоящее время я объявил в своей процедуре PL / SQL переменную msg типа MESSAGE. Если я введу INSERT в эту переменную, а затем добавлю INSERT эту переменную в таблицу, содержащую столбец типа MESSAGE (и пару других столбцов, которые я использую для предварительной обработки), как я могу выполнить new INSERT s в fresh new переменную msg?

Спасибо

Ответы [ 2 ]

2 голосов
/ 17 октября 2011

Если вы объявили MESSAGE как TABLE OF CHAR(120), TABLE OF CHAR(120) INDEX BY BINARY_INTEGER или VARRAY(...) OF CHAR(120), тогда вы можете сделать

msg.DELETE;

Методы DELETE для вложенных таблиц,Таблицы index-by и переменные удаляют из них все элементы.

Когда вы INSERT msg добавляете в таблицу, кажется, что Oracle хранит ее копию, а не ссылку на нее.Удаление всех элементов из msg не приведет к внезапному исчезновению данных в вашей таблице.

В качестве альтернативы, если MESSAGE является TABLE OF CHAR(120) или VARRAY(...) OF CHAR(120), вы можете вызвать MESSAGE() конструктор, то есть

msg := MESSAGE();
1 голос
/ 17 октября 2011
declare
  type message_t is table of char(120);
  v_message message_t := message_t('12 record', /* start */
                                   '40 record',
                                   '70 record', /* end */
                                   '12 record', /* start */
                                   '50 record',
                                   '51 record',
                                   '70 record'  /* end */
                                   );
  v_almessage message_t := message_t();
  v_i number := v_message.first;
begin
  while v_i <= v_message.last loop
    if v_message(v_i) = '12 record' then /* start of a block */
      dbms_output.put_line('start of a block');

      loop
        v_i := v_i + 1;

        if v_message(v_i) = '70 record' then /* end of a block */
          dbms_output.put_line('end of a block');

          /* Do whatever processing you need to do. I just print collected
          messages. */
          for j in v_almessage.first .. v_almessage.last loop
            dbms_output.put_line('aligment message: ' || v_almessage(j)); 
          end loop;

          /* Reset collected messages. */
          v_almessage := message_t();

          exit;
        end if;

        /* Collect block's aligment messages. */
        v_almessage.extend(1);
        v_almessage(v_almessage.last) := v_message(v_i);
      end loop;

    end if;

    v_i := v_i + 1;
  end loop;

end;
/

Печать:

start of a block
end of a block
aligment message: 40 record
start of a block
end of a block
aligment message: 50 record
aligment message: 51 record
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...