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

Откуда: Москва->Петушки
Сообщений: 8258
Добрый день, коллеги!

Версия Oracle: 19c Enterprise 19.0.0.0.0.
Хочу написать функцию возвращающую таблицу.
На уровне схемы получается неплохо
CREATE OR REPLACE TYPE STR_RECORD IS OBJECT(
    STR1 VARCHAR2(255),
    STR2 VARCHAR2(255)
  )
/
CREATE OR REPLACE TYPE STR_TABLE IS TABLE OF STR_RECORD
/
CREATE OR REPLACE FUNCTION GET_STR_TABLE
  RETURN STR_TABLE IS
  TBL STR_TABLE;
BEGIN
  SELECT STR_RECORD('STR1_VAL', 'STR2_VAL')
  BULK COLLECT INTO TBL
  FROM DUAL;

  RETURN TBL;
END;
/
SELECT * FROM TABLE(GET_STR_TABLE)


Теперь хотелось бы убарть функцию в пакет. Однако, тут возникают проблемы, потому что объекты не поддерживаются в контексте пакета. Если заменить IS OBJECT на IS RECORD, как-то так

CREATE OR REPLACE PACKAGE TEST AS
  TYPE STR_RECORD IS RECORD(
      STR1 VARCHAR2(255),
      STR2 VARCHAR2(255)
    );

  TYPE STR_TABLE IS TABLE OF STR_RECORD;

  FUNCTION GET_STR_TABLE
    RETURN STR_TABLE;
END;
/

CREATE OR REPLACE PACKAGE BODY TEST AS
  FUNCTION GET_STR_TABLE
    RETURN STR_TABLE IS
    TBL STR_TABLE;
  BEGIN
   SELECT STR_RECORD('STR1_VAL', 'STR2_VAL')
   BULK COLLECT INTO TBL
   FROM DUAL;

    RETURN TBL;
  END;
END;
/
SELECT * FROM TABLE(TEST.GET_STR_TABLE)

то я получаю на селекте ошибку компиляции ORA-00913: слишком много значений.
Если заменить SELECT STR_RECORD('STR1_VAL', 'STR2_VAL') на SELECT 'STR1_VAL', 'STR2_VAL', то функция компилируется, но падает при вызове с ошибкой ORA-00902: неверный тип данных.
Как мне убрать обозначенную выше функцию GET_STR_TABLE в пакет?
2 июн 21, 11:15    [22330209]     Ответить | Цитировать Сообщить модератору
 Re: is record vs is object  [new]
Stax
Member

Откуда: Ukraine,Lviv
Сообщений: 3070
.NET

потому что объекты не поддерживаются в контексте пакета.

в каком смысле не поддерживаются?

.....
stax

Сообщение было отредактировано: 2 июн 21, 11:42
2 июн 21, 11:49    [22330234]     Ответить | Цитировать Сообщить модератору
 Re: is record vs is object  [new]
.NET
Member

Откуда: Москва->Петушки
Сообщений: 8258
Stax
.NET

потому что объекты не поддерживаются в контексте пакета.

в каком смысле не поддерживаются?

.....
stax

ORA-00540: объект не поддерживается в этом контексте
2 июн 21, 11:59    [22330240]     Ответить | Цитировать Сообщить модератору
 Re: is record vs is object  [new]
oragraf
Member

Откуда: Moscow
Сообщений: 1347
.NET,

1. у record нет конструктора
2. функция должна быть pipelined
2 июн 21, 12:29    [22330255]     Ответить | Цитировать Сообщить модератору
 Re: is record vs is object  [new]
Stax
Member

Откуда: Ukraine,Lviv
Сообщений: 3070
.NET,
SQL> CREATE OR REPLACE PACKAGE TEST_net AS
  2
  3    FUNCTION GET_STR_TABLE
  4      RETURN STR_TABLE;
  5  END;
  6  /

Пакет создан.

SQL> CREATE OR REPLACE PACKAGE BODY TEST_net AS
  2    FUNCTION GET_STR_TABLE
  3      RETURN STR_TABLE IS
  4      TBL STR_TABLE;
  5    BEGIN
  6     SELECT STR_RECORD('STR1_VAL', 'STR2_VAL')
  7     BULK COLLECT INTO TBL
  8     FROM DUAL;
  9
 10      RETURN TBL;
 11    END;
 12  END;
 13  /

Тело пакета создано.


SQL> ed
Записано file afiedt.buf

  1* SELECT * FROM TABLE(TEST_net.GET_STR_TABLE)
SQL> /

STR1
--------------------------------------------------------------------------------
STR2
--------------------------------------------------------------------------------
STR1_VAL
STR2_VAL


SQL>


.....
stax
2 июн 21, 12:33    [22330257]     Ответить | Цитировать Сообщить модератору
 Re: is record vs is object  [new]
.NET
Member

Откуда: Москва->Петушки
Сообщений: 8258
Stax,

Да, действительно, если типы вообще не объявлять, то все прекрасно работает, если типы уже определены до этого на уровне схемы.
Спасибо.

Сообщение было отредактировано: 2 июн 21, 12:58
2 июн 21, 13:01    [22330274]     Ответить | Цитировать Сообщить модератору
 Re: is record vs is object  [new]
Sayan Malakshinov
Member

Откуда: Мск
Сообщений: 5888
.NET
функцию возвращающую таблицу.
если хотите использовать в SQL, делайте лучше pipelined функцию с pipe row (STR_RECORD('STR1_VAL', 'STR2_VAL'))

pipelined vs non-pipelined
2 июн 21, 13:07    [22330278]     Ответить | Цитировать Сообщить модератору
 Re: is record vs is object  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10215
oragraf
.NET,

1. у record нет конструктора


Зависит от версии:

SQL> select banner from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production

SQL> DECLARE
  2      TYPE STR_RECORD IS RECORD(
  3                                STR1 VARCHAR2(255),
  4                                STR2 VARCHAR2(255)
  5                               );
  6      V_STR_RECORD STR_RECORD;
  7  BEGIN
  8      V_STR_RECORD := STR_RECORD('ABC','DEF');
  9  END;
 10  /

PL/SQL procedure successfully completed.

SQL>


SY.
2 июн 21, 13:45    [22330302]     Ответить | Цитировать Сообщить модератору
 Re: is record vs is object  [new]
oragraf
Member

Откуда: Moscow
Сообщений: 1347
SY
Зависит от версии:

Прикольно, и правда:
declare
    type str_record is record(
        str1 varchar2(255) not null := 'AA',
        str2 varchar2(255));
    v_str_record str_record := str_record(str2 => 'DEF');
begin
    null;
end;
/
Спасибо, Соломон.
3 июн 21, 00:54    [22330659]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить