Как вернуть из хранимой процедуры список записей?
Ка создать хранимую процедуру, которая бы запрашивала данные из таблицы без параметров и/или по какому-то параметру и возвращала список записей?
При этому вызов процедуры можно было бы сделать через call, чтобы проверить:
CREATE OR REPLACE PROCEDURE GET_ALL_EMPLOYEES
IS
BEGIN
SELECT * from EMPLOYEES ;
END GET_ALL_EMPLOYEES;
Procedure GET_ALL_EMPLOYEES compiled
LINE/COL ERROR
--------- ------------------------------------------------------------- 4/2
PLS-00428: в этом предложении SELECT ожидается фраза INTO Errors: check compiler log
call get_all_employees();
Procedure GET_ALL_EMPLOYEES compiled
LINE/COL ERROR --------- ------------------------------------------------------------- 7/1
PLS-00103: Встретился символ "CALL" Errors: check compiler log
Вот такой вариант :
create or replace PROCEDURE TESTPRGTWO
IS
L_CUR SYS_REFCURSOR;
BEGIN
open l_cur FOR select * from employees;
END;
Это не работает.
SELECT OBJECT_NAME, OBJECT_TYPE, STATUS
FROM USER_OBJECTS
WHERE OBJECT_TYPE = 'PROCEDURE';
В консоли вижу только
call TESTPRGTWO();
Кто может подсказать, как это все сделать?
Обновление
A вот как делается в MySQL:
обновление_2
А вот какое громоздкое решение и это только полей 4, а бывает по 30 и более, и что делать?
-- Меняем схему на свою
-- 1 Cоздаем объект с перечислением необходимых полей, которые должны быть выведены из выбираемой таблицы.
--DROP TYPE OBJ_EMPL;
CREATE OR REPLACE TYPE OBJ_EMPL AS OBJECT
(
employeeID NUMBER(19,0),
address VARCHAR2(100 CHAR),
first_Name VARCHAR2(50 CHAR),
last_Name VARCHAR2(50 CHAR)
);
-- 2 создаем коллекцию объектов - таблицу, из полей ранее определенного типа OBJ_EMPL. Данная таблица появляется в момент
-- вызова переменной LIST_OBJ_EMPL и создается на основе полей, которые были объявлены в ранее созданном типе OBJ_EMPL.
--DROP TYPE LIST_OBJ_EMPL;
CREATE OR REPLACE TYPE LIST_OBJ_EMPL IS TABLE OF OBJ_EMPL;
-- 3 создаем функцию, чтобы возратить результат.
-- getListEmployees - название функции
-- LIST_OBJ_EMPL - тип переменной в которую будет записан результат выборки (может писаться много строк)
-- varObjEmpl - имя локальной переменной, а LIST_OBJ_EMPL - это тип объявленной локальной переменной
CREATE OR REPLACE FUNCTION getListEmployees RETURN LIST_OBJ_EMPL IS
varObjEmpl LIST_OBJ_EMPL;
-- начинается выполнение команды
BEGIN
SELECT OBJ_EMPL ( -- После селекта указывается сам объект, с перечислением полей. То есть мы указываем, что нужно обратиться к типу OBJ_EMPL,
-- в котором мы перечислили поля (которые нужно вернуть из таблицы)
employeeID,
first_Name,
last_Name,
address
)
--- большое количество (данных) собирается в указанную ранее локальную переменную, которая имеет ссылку на тип LIST_OBJ_EMPL
BULK COLLECT INTO varObjEmpl
FROM EMPLOYEES; -- указывается, из какого объекта будет произведена выборка полей
RETURN varObjEmpl; -- вернули в точку вызова полученные записи из таблицы
EXCEPTION
WHEN NO_DATA_FOUND THEN
return NULL;
WHEN OTHERS THEN
-- Consider logging the error and then re-raise
RAISE;
END getListEmployees;
/
-- Вызов функции
--SELECT * FROM TABLE(getListEmployees);
-- Создание таблицы
/*
CREATE TABLE EMPLOYEES
(EMPLOYEEID NUMBER(19,0) NOT NULL ENABLE,
ADDRESS VARCHAR2(100 CHAR),
FIRST_NAME VARCHAR2(50 CHAR),
LAST_NAME VARCHAR2(50 CHAR),
CONSTRAINT PK_EMPLOYEEID PRIMARY KEY (EMPLOYEEID)
);
*/
вызов функции вот такой
SELECT * FROM TABLE(getListEmployees);
Кто может подсказать, как это все сделать, как упростить и сделать процедуру, но не функцию?
Ответы (1 шт):
По порядку с самого простого, которое в вопросе:
вот такой вариант: [...] PROCEDURE TESTPRGTWO [...] Это не работает.
Не работает потому, что результат надо вернуть. С версии 12.1 будет доступна dbms_sql.return_result, а пока, не на много сложнее, так:
create or replace type numList is table of number
/
create or replace procedure testprgtwo (ids numList, rc out sys_refcursor) is
begin
open rc for
select employee_id, first_name, last_name
from hr.employees e
join table (ids) t on t.column_value = e.employee_id
order by 1;
end;
/
Получить результат:
set autoprint on
var rc refcursor
exec testprgtwo (numList(191,199), :rc);
EMPLOYEE_ID FIRST_NAME LAST_NAME
----------- -------------------- -------------------------
191 Randall Perkins
199 Douglas Grant



