Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 непоследовательного заполнения коллекций  [new]
rekrabbe
Member

Откуда:
Сообщений: 29
В книге PL/SQL для профессионалов есть пример непоследовательного заполнения коллекции с использованием функции, в сигнатуре которой есть один параметр.
DROP TABLE hairstyles;

CREATE TABLE hairstyles (
   code INTEGER,
   description VARCHAR2(100)
   );

INSERT INTO hairstyles VALUES (1000, 'CREWCUT');
INSERT INTO hairstyles VALUES (1001, 'BOB');
INSERT INTO hairstyles VALUES (1002, 'SHAG');
INSERT INTO hairstyles VALUES (1003, 'BOUFFANT');
INSERT INTO hairstyles VALUES (1004, 'PAGEBOY');

CREATE OR REPLACE PACKAGE justonce
IS
   FUNCTION description (code_in IN hairstyles.code%TYPE)
      RETURN hairstyles.description%TYPE;
END justonce;
/

CREATE OR REPLACE PACKAGE BODY justonce
IS
   TYPE desc_t IS TABLE OF hairstyles.description%TYPE
      INDEX BY BINARY_INTEGER;
   descriptions   desc_t;

   FUNCTION description (code_in IN hairstyles.code%TYPE)
      RETURN hairstyles.description%TYPE
   IS
      return_value   hairstyles.description%TYPE;

      FUNCTION desc_from_database RETURN hairstyles.description%TYPE
      IS
         CURSOR desc_cur IS
            SELECT description FROM hairstyles WHERE code = code_in;
         desc_rec   desc_cur%ROWTYPE;
      BEGIN
         OPEN desc_cur;
         FETCH desc_cur INTO desc_rec;
         RETURN desc_rec.description;
      END;
   BEGIN
      RETURN descriptions (code_in);
   EXCEPTION
      WHEN NO_DATA_FOUND 
	  THEN
         descriptions (code_in) := desc_from_database;
         RETURN descriptions (code_in);
   END;
END justonce;
/

BEGIN
   DBMS_OUTPUT.PUT_LINE (justonce.description (1000));
   DBMS_OUTPUT.PUT_LINE (justonce.description (1002));
   DBMS_OUTPUT.PUT_LINE (justonce.description (1004));
END;
/

Вопрос как сделать тоже самое, если в сигнатуре функции 2 и более параметров? Непонятно какую коллекцию нужно будет использовать. Т.е. должно быть, что то типа:
BEGIN
      RETURN descriptions (code_in, param1_in, param2_in);
   EXCEPTION
      WHEN NO_DATA_FOUND 
	  THEN
         descriptions (code_in, param1_in, param2_in) := desc_from_database;
         RETURN descriptions (code_in, param1_in, param2_in);
   END;

Напишите возможно ли это и пример кода пожалуйста.
8 фев 17, 14:17    [20193039]     Ответить | Цитировать Сообщить модератору
 Re: непоследовательного заполнения коллекций  [new]
Elic
Member

Откуда: 1984. Выбраковка финно-угром началась. КЯЗ
Сообщений: 27381
rekrabbe
если в сигнатуре функции 2 и более параметров?
Коллекция коллекций.
8 фев 17, 14:30    [20193147]     Ответить | Цитировать Сообщить модератору
 Re: непоследовательного заполнения коллекций  [new]
--Eugene--
Member

Откуда: Боярышник
Сообщений: 2042
rekrabbe,

хреновую книгу ты читаешь, imho
8 фев 17, 14:35    [20193193]     Ответить | Цитировать Сообщить модератору
 Re: непоследовательного заполнения коллекций  [new]
rekrabbe
Member

Откуда:
Сообщений: 29
--Eugene--
rekrabbe,

хреновую книгу ты читаешь, imho

Какая получше будет? Официальная дока?
8 фев 17, 14:40    [20193227]     Ответить | Цитировать Сообщить модератору
 Re: непоследовательного заполнения коллекций  [new]
fortnet
Member

Откуда:
Сообщений: 519
Коллекция записей
8 фев 17, 16:17    [20193885]     Ответить | Цитировать Сообщить модератору
 Re: непоследовательного заполнения коллекций  [new]
dbms_photoshop
Member

Откуда: sqlmdx.net
Сообщений: 4845
rekrabbe
--Eugene--
rekrabbe,

хреновую книгу ты читаешь, imho

Какая получше будет? Официальная дока?
Самое лучшее что мне попадалось - Doing SQL from PL/SQL: Best and Worst Practices.
Правда у новичка может закипеть мозг.
8 фев 17, 16:26    [20193942]     Ответить | Цитировать Сообщить модератору
 Re: непоследовательного заполнения коллекций  [new]
rekrabbe
Member

Откуда:
Сообщений: 29
Спасибо.
Не получилось реализовать задуманное, создав коллекцию записей непонятно как вернуть данные из нее.
Создавал ее так:
TYPE my_rec IS RECORD (
  r_code hairstyles.code%TYPE,
  r_grp hairstyles.grp%TYPE
);
TYPE my_array IS TABLE OF my_rec INDEX BY BINARY_INTEGER;
my_table my_array ;

Конструкция вида
RETURN my_table(my_rec(code_in, grp_in))

Не работает.
10 фев 17, 09:00    [20199149]     Ответить | Цитировать Сообщить модератору
 Re: непоследовательного заполнения коллекций  [new]
fortnet
Member

Откуда:
Сообщений: 519
rekrabbe,

В такой реализации не получится, т.к. pl/sql таблица предполагает , что индекс уникальный. Если добавляются параметры, значит ключ должен уже быть составным. К примеру :
CREATE OR REPLACE PACKAGE BODY justonce
IS
   TYPE desc_t IS TABLE OF hairstyles.description%TYPE
      INDEX BY BINARY_INTEGER;
   descriptions   desc_t;

   FUNCTION description (code_in IN hairstyles.code%TYPE,grp_in in hairstyles.grp%TYPE)
      RETURN hairstyles.description%TYPE
   IS
      return_value   hairstyles.description%TYPE;

      FUNCTION desc_from_database RETURN hairstyles.description%TYPE
      IS
         CURSOR desc_cur IS
            SELECT description FROM hairstyles WHERE code|| grp = code_in || grp_in ;
         desc_rec   desc_cur%ROWTYPE;
      BEGIN
         OPEN desc_cur;
         FETCH desc_cur INTO desc_rec;
         RETURN desc_rec.description;
      END;
   BEGIN
      RETURN descriptions (code_in || grp_in);
   EXCEPTION
      WHEN NO_DATA_FOUND
    THEN
         descriptions (code_in || grp_in) := desc_from_database;
         RETURN descriptions (code_in || grp_in);
   END;
END justonce;
17 фев 17, 12:10    [20220733]     Ответить | Цитировать Сообщить модератору
 Re: непоследовательного заполнения коллекций  [new]
NetWeight
Member

Откуда:
Сообщений: 14
+
drop table
HAIRSTYLES
/
create table
HAIRSTYLES
( grp          INTEGER
, code         INTEGER
, description  VARCHAR2( 100 )
)
/
insert into HAIRSTYLES values ( 1, 1000, 'CREWCUT')
/
insert into HAIRSTYLES values ( 1, 1001, 'BOB')
/
insert into HAIRSTYLES values ( 2, 1002, 'SHAG')
/
insert into HAIRSTYLES values ( 2, 1003, 'BOUFFANT')
/
insert into HAIRSTYLES values ( 3, 1004, 'PAGEBOY')
/

DECLARE
    type CODE_REC  is record ( description  HAIRSTYLES.description%type
                             ) ;
    type CODE_TBL  is table of CODE_REC index by BINARY_INTEGER;
    type GRP_REC   is record ( t_code  CODE_TBL
                             ) ;
    type GRP_TBL   is table of GRP_REC index by BINARY_INTEGER;
    t_grp          GRP_TBL;


    ----------------------------------------------------------------
    --    
    ----------------------------------------------------------------
    FUNCTION DESC_FROM_DATABASE
         ( i_grp                INTEGER
         , i_code               INTEGER
         )
    RETURN   HAIRSTYLES.description%type
    IS
        CURSOR desc_cur
        IS
            select description
              from HAIRSTYLES
             where 1    = 1
               and grp  = i_grp
               and code = i_code;

        desc_rec  desc_cur%rowtype;

    BEGIN
        BEGIN DBMS_OUTPUT.PUT_LINE( '    BEGIN: DESC_FROM_DATABASE' );

            open desc_cur;

            fetch desc_cur
             into desc_rec;

        DBMS_OUTPUT.PUT_LINE( '    END: DESC_FROM_DATABASE' ); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE( '        DESC_FROM_DATABASE: EXCEPTION' ); RAISE;
        END;

        RETURN desc_rec.description;

    END DESC_FROM_DATABASE;


    ----------------------------------------------------------------
    --    
    ----------------------------------------------------------------
    FUNCTION DESC_FROM_TBL
         ( i_grp           INTEGER
         , i_code          INTEGER
         )
    RETURN   HAIRSTYLES.description%type
    IS
        v_return           HAIRSTYLES.description%type;

    BEGIN 
        BEGIN DBMS_OUTPUT.PUT_LINE( '    BEGIN: DESC_FROM_TBL' );

            v_return := t_grp( i_grp ).t_code( i_code ).description;

        DBMS_OUTPUT.PUT_LINE( '    END: DESC_FROM_TBL' );
        EXCEPTION
            WHEN NO_DATA_FOUND
            THEN
                DBMS_OUTPUT.PUT_LINE( '        DESC_FROM_TBL: NO_DATA_FOUND' );
                RAISE NO_DATA_FOUND;

        END;

        RETURN v_return;

    END DESC_FROM_TBL;


    ----------------------------------------------------------------
    --    
    ----------------------------------------------------------------
    FUNCTION DESCRIPTION
        ( i_grp          HAIRSTYLES.grp%type
        , i_code         HAIRSTYLES.code%type
        )
    RETURN HAIRSTYLES.description%type
    IS
        v_return         HAIRSTYLES.description%type;

    BEGIN
        BEGIN DBMS_OUTPUT.PUT_LINE( 'BEGIN: DESCRIPTION' );

            DBMS_OUTPUT.PUT_LINE( '    i_grp  = ' || i_grp  );
            DBMS_OUTPUT.PUT_LINE( '    i_code = ' || i_code );

            BEGIN 
                v_return := DESC_FROM_TBL
                                ( i_grp  => i_grp
                                , i_code => i_code
                                ) ;

            EXCEPTION
                WHEN NO_DATA_FOUND 
                THEN
                    DBMS_OUTPUT.PUT_LINE( '    DESCRIPTION: EXCEPTION' );

                    t_grp( i_grp ).t_code( i_code ).description := DESC_FROM_DATABASE
                                                                       ( i_grp  => i_grp
                                                                       , i_code => i_code
                                                                       ) ;
                    v_return := DESC_FROM_TBL
                                    ( i_grp  => i_grp
                                    , i_code => i_code
                                    ) ;

            END;

            DBMS_OUTPUT.PUT_LINE( 'v_return = ' || v_return );

        DBMS_OUTPUT.PUT_LINE( 'END: DESCRIPTION' );
        END;

        RETURN v_return;

    END DESCRIPTION;


    ----------------------------------------------------------------
BEGIN
    DBMS_OUTPUT.PUT_LINE( DESCRIPTION( 1, 1000 ) );
    DBMS_OUTPUT.PUT_LINE( DESCRIPTION( 2, 1002 ) );
    DBMS_OUTPUT.PUT_LINE( DESCRIPTION( 3, 1004 ) );
    DBMS_OUTPUT.PUT_LINE( DESCRIPTION( 3, 1004 ) );

EXCEPTION
    WHEN OTHERS
    THEN
        RAISE;

END;
30 мар 17, 14:14    [20350941]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить