Как я могу вернуть данные собственного типа в хранимой процедуре Oracle? - PullRequest
1 голос
/ 14 июня 2019

Я создаю данные типа в oracle для процедуры.

процедура:

create or replace TYPE ROW_USER as object 
(
    ID                  NUMBER(4),
    ROLES_ID            NUMBER(1),
    FIRST_NAME          VARCHAR2(60 BYTE),
    SECOND_NAME         VARCHAR2(60 BYTE),
    FIRST_LAST_NAME     VARCHAR2(60 BYTE),
    SECOND_LAST_NAME    VARCHAR2(60 BYTE),
    CC                  NUMBER(10,0),
    EMAIL               VARCHAR2(60 BYTE)
);

и:

create or replace type NESTED_ROW_USER as table of ROW_USER;

когда я использую данные этого типа в анонимном блоке, и он работает.

set serveroutput on; 
DECLARE  
    ROWUSR NESTED_ROW_USER;
BEGIN
    select cast( multiset(select id, ROLES_ID, FIRST_NAME, SEGUNDO_NOMBRE, 
    FIRST_LAST_NAME, SECOND_LAST_NAME, CC, EMAIL from USERS where id =  1) as 
    NESTED_ROW_USER)
       into ROWUSR
    from users;  

DBMS_OUTPUT.PUT_LINE(ROWUSR(1).id||','||ROWUSR(1).ROLES_ID||','|| 
    ROWUSR(1).FIRST_NAME);
    END;

результат блока:

Process PL/SQL exited successfully.
1,1,DIEGO

Но когда я использую его в хранимой процедуре, чтобы вернуть его, я получаю сообщение об ошибке.

Процедура:

create or replace PROCEDURE outnested(ROWUSR OUT NESTED_ROW_USR)
AS
BEGIN
  select cast( multiset(select id, ROLES_ID, FIRST_NAME, SECOND_NAME, 
  FIRST_LAST_NAME, SECOND_LAST_NAME, CC, EMAIL from USERS where id =  1) as 
  NESTED_ROW_USER)
    into ROWUSR
    from users;     
END;

ошибка:

ORA-06550: line 5, column 16:
PLS-00302: component 'NESTED_ROW_USER' must be declared
ORA-06550: line 5, column 11:
PL/SQL: Item ignored
ORA-06550: line 14, column 16:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 10, column 3:
PL/SQL: Statement ignored

Почему он не возвращает значение?

Ответы [ 2 ]

1 голос
/ 15 июня 2019

Я запустил ваш DDL в базе данных Oracle 12c, заменив почтенную таблицу EMP на вашу таблицу usuario, и она, похоже, сработала.

Таблицы Oracle EMP и DEPT

Единственная потенциальная ошибка, которую я заметил, заключалась в том, что вы включили from usuario дважды в свой запрос: один раз для мультимножества и один раз как источник внешнего SELECT.В конце запроса я заменил from dual на from usuario.

Для удобства я удалил предложение WHERE;Я предполагаю, что вы сохраните его.

Убедитесь, что тип NESTED_FILA_USUARIO принадлежит той же схеме, что и процедура outnested, иначе вам придется включить префикс имени схемы и убедиться, чтосуществует прямое разрешение от владельца NESTED_FILA_USUARIO на схему outnested (роли не работают в скомпилированном PL / SQL).

create or replace TYPE FILA_USUARIO as object 
(
  EMPNO NUMBER(4),
  ENAME VARCHAR2(10),
  JOB   VARCHAR2(9),
  MGR   NUMBER(4),
  HIREDATE DATE,
  SAL NUMBER(7,2),
  COMM NUMBER(7,2),
  DEPTNO NUMBER(2)
);
create or replace type NESTED_FILA_USUARIO as table of FILA_USUARIO;

Вотанонимный блок:

DECLARE  
    FILAUSU NESTED_FILA_USUARIO;
BEGIN
    select cast( multiset(select EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO from EMP) as 
    NESTED_FILA_USUARIO)
       into FILAUSU
    from dual;  

DBMS_OUTPUT.PUT_LINE(FILAUSU(1).EMPNO||','||FILAUSU(1).ENAME||','|| 
    FILAUSU(1).JOB);
END;

Вот хранимая процедура с тестом:

create or replace PROCEDURE outnested(FILAUSU OUT NESTED_FILA_USUARIO)
AS
BEGIN
  select cast( multiset(select EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO from EMP) as 
  NESTED_FILA_USUARIO)
    into FILAUSU
    from dual;     
END;
/
declare
  filausu NESTED_FILA_USUARIO;
begin
  outnested(filausu);
  DBMS_OUTPUT.PUT_LINE(FILAUSU(1).EMPNO||','||FILAUSU(1).ENAME||','|| 
    FILAUSU(1).JOB);
end;
/

Вывод был такой:

7839, KING, PRESIDENT

И это ожидается для этого запроса.

1 голос
/ 14 июня 2019

Вы действительно пытаетесь создать коллекцию с таким же количеством строк, как у таблицы usarios, с одинаковыми значениями объектов в каждом элементе коллекции?Это кажется странным.

Я предполагаю, что вы действительно хотите что-то вроде этого

create or replace PROCEDURE outnested(p_FILAUSU OUT NESTED_FILA_USUARIO)
AS
BEGIN
  select FILA_USUARIOr( id, 
                        ROLES_ID, 
                        PRIMER_NOMBRE, 
                        SEGUNDO_NOMBRE, 
                        PRIMER_APELLIDO, 
                        SEGUNDO_APELLIDO, 
                        CC, 
                        EMAIL )
    bulk collect into p_FILAUSU 
    from USUARIOS 
   where id =  1;
END;
...