Блог по программированию в среде Delphi

Поиск по блогу

Есть идея по созданию интересной программы?

Опиши тут и я по возможности постараюсь это реализовать специально для тебя! Без $ ))

четверг, 24 апреля 2014 г.

Хранимая процедура и параметры IN и OUT массив и массив записей соотвественно (ORACLE)

Логотип Oracle
 Необходимо было сделать хранимую процедуру для ORACLE.
По началу показалось делов-то, но потом выяснилось, что у Оракла есть несколько типов массивов:

1. VARRAYS - фиксированной длины
2. PL/SQL- таблицы INDEX BY BINARY_INTEGER ( Ассоциативный массив)
3. Nested Tables
 Мне необходимо было реализовать процедуру, используя последний тип массива т.е. Nested Tables.


Изначально все было прекрасно, т.к. я использовал в разработке процедуры ассоциативный массив, оказалось у него есть несколько плюшечек, а может и не плюшек, но удобно. Оказалось, что ассоциативные массивы нет необходимости инициализировать и расширять в процессе их использования.
 Когда, я познал эту вещь пришлось заменять тип данных используемых в процедуре на необходимый нам Nested Tables. И тут началось)))
Оракл постоянно матерился то на размер, то на то, что переменная не инициализирована, мозг просто взрывался...

Что делать? Извечный вопрос, но тут уже, ни кто кроме нас, не сделает, сработало))

Сел. Подумал. И давай рыть интернет. Информации просто гора, только в основном примеры элементарные.

В общем вот, что у меня получилось!
/*пакет*/
CREATE OR REPLACE PACKAGE test_pack IS
   
    TYPE T_TestRecord IS RECORD ( v_Test VARCHAR2(20), n_Test number);
   
    TYPE T_TestRecords IS TABLE OF T_TestRecord INDEX BY BINARY_INTEGER;

    TYPE T_TestRecords2 IS TABLE OF T_TestRecord;
   
    PROCEDURE TestProcedure(pTest1 IN T_TestRecords, pTest2 out T_TestRecords2);
   
END test_pack;

/*тело пакета*/
CREATE OR REPLACE PACKAGE BODY test_pack
AS
BEGIN
/*процедура*/   
PROCEDURE TestProcedure(pTest1 IN T_TestRecords, pTest2 out T_TestRecords2)
    as
    BEGIN
        if pTest1.count=0 then
            return;
        end if;
        /*инициализировал тут по той причине, что в случае возникновения исключительной
        ситуации необходимо было занести значения в массив по конкретному запросу */
        pTest2:=T_TestRecords2();
        pTest2.extend(pTest1.count);

        for i in 1..pTest1.count loop
            /*тут производятся манипуляции с данными
            в итоге типа вот такого))*/
            if pTest1(i)='hi' then
                pTest2(i).v_Test:='YES';
                pTest2(i).n_Test:=1;
            else
                pTest2(i).v_Test:='NO';
                pTest2(i).n_Test:=0;
            end if;
        end loop;
    END;
END test_pack;

/*вызов хранимой процедуры*/
DECLARE
    testArray test_pack.T_TestRecords := test_pack.T_TestRecords();
    testArray2 test_pack.T_TestRecords2;
begin
    testArray1.extend(2);
    testArray1(1):='hi';
    testArray1(2):='nohi';
   
    test_pack.Nested Tables(testArray,testArray2);
   
    for i in 1 ..testArray2.count
    loop
        dbms_output.put_line(testArray2(i).v_Test);
        dbms_output.put_line(TO_CHAR(testArray2(i).n_Test));
    end loop;
   
end;

Все работает прекрасно!
Спасибо за внимание!

Комментариев нет:

Отправить комментарий