Я пытаюсь обернуть некоторый SQL в процедуру PLSQL, чтобы пользователь мог передавать параметры вместо того, чтобы вручную редактировать предложение WHERE, что дало бы им возможность сломать рабочий код. Код SQL, который я переношу, встроен в PROCEDURE, за исключением предложения INTO.
Я знаю, что в PLSQL для выбора строк должно быть предложение INTO. Оглядевшись, я увидел пример, который создает объект и тип таблицы. Что-то я не хотел делать и кажется мне слишком сложным. Если возможно, я хочу, чтобы все было локально для процедуры.
Я также открыт для использования BULK-сбора в таблице access_history, если это будет более эффективным методом.
Когда я пытаюсь создать описанную ниже процедуру, она не работает, и здесь я могу воспользоваться помощью и знаниями PLSQL, чтобы найти наилучшее направление для получения нужных данных.
Во-вторых, есть ли способ использовать значение DEFAULT для определения количества извлекаемых строк.
Если процедура вызывается следующим образом:
EXEC LAST_EMPLOYEE_HISTORY(1) означает получение последних 20 (ПО УМОЛЧАНИЮ) строк для employee_id=1, где 20 — значение по умолчанию.
Если процедура вызывается следующим образом:
EXEC LAST_EMPLOYEE_HISTORY(1, 50) означает получение последних 50 строк для employee_id=1.
Буду очень признателен за любую помощь и опыт в объяснении и помощи в решении моих проблем. Заранее спасибо всем ответившим.
Ниже мой тестовый СЛУЧАЙ.
ALTER SESSION SET NLS_DATE_FORMAT = 'MMDDYYYY HH24:MI:SS';
CREATE OR REPLACE TYPE access_history_obj AS OBJECT(
employee_id NUMBER(6),
first_name VARCHAR2(20),
last_name VARCHAR2(20),
card_num VARCHAR2(10),
location_id NUMBER(6),
location_name VARCHAR2(30),
access_date DATE
);
CREATE OR REPLACE TYPE access_history_table IS TABLE OF access_history_obj;
Create table employees(
employee_id NUMBER(6),
first_name VARCHAR2(20),
last_name VARCHAR2(20),
card_num VARCHAR2(10),
work_days VARCHAR2(7)
);
INSERT INTO employees (
employee_id,
first_name,
last_name,
card_num,
work_days
)
WITH names AS (
SELECT 1, 'John', 'Doe', 'D564311','YYYYYNN' FROM dual UNION ALL
SELECT 2, 'Justin', 'Case', 'C224311','YYYYYNN' FROM dual UNION ALL
SELECT 3, 'Mike', 'Jones', 'J288811','YYYYYNN' FROM dual UNION ALL
SELECT 4, 'Jane', 'Smith', 'S564661','YYYYYNN' FROM dual
) SELECT * FROM names;
CREATE TABLE locations AS
SELECT level AS location_id,
'Door ' || level AS location_name,
CASE round(dbms_random.value(1,3))
WHEN 1 THEN 'A'
WHEN 2 THEN 'T'
WHEN 3 THEN 'T'
END AS location_type
FROM dual
CONNECT BY level <= 5;
create table access_history(
seq_num integer GENERATED BY DEFAULT AS IDENTITY (START WITH 1) NOT NULL,
employee_id NUMBER(6),
card_num varchar2(10),
location_id number(4),
access_date date,
processed NUMBER(1) default 0
);
INSERT INTO access_history(
employee_id,
card_num,
location_id,
access_date
)
WITH rws AS (
SELECT 1,'J11111',2,TO_DATE('2021/08/15 08:30:25', 'YYYY/MM/DD HH24:MI:SS') FROM dual UNION ALL
SELECT 1,'J11111',3,TO_DATE('2021/08/15 18:30:35', 'YYYY/MM/DD HH24:MI:SS') FROM dual UNION ALL
SELECT 2,'E11111',2,TO_DATE('2021/08/15 11:20:35', 'YYYY/MM/DD HH24:MI:SS') FROM dual) SELECT * FROM rws;
CREATE OR REPLACE PROCEDURE LAST_EMPLOYEE_HISTORY(
p_employee_id IN NUMBER,
p_rws IN number)
AS
BEGIN
with rws as (
select e.employee_id,
e.first_name,
e.last_name,
e.card_num,
l.location_id,
l.location_name,
a.access_date,
row_number () over
(
partition by e.employee_id
order by a.access_date DESC
) rn
FROM employees e
JOIN access_history a ON a.employee_id = e.employee_id
JOIN locations l ON l.location_id = a.location_id
)
select employee_id,
first_name,
last_name,
card_num,
location_id,
location_name,
access_date INTO access_history_table
from rws
where
employee_id = p_employee_id AND
rn <= p_rws
order by employee_id, access_date desc;
END;
EXEC LAST_EMPLOYEE_HISTORY(1)
Вы можете рассмотреть возможность использования табличной функции вместо процедуры.
@sticky bit Я не хочу ВСТАВЛЯТЬ строки, мне просто нужно ВЫБРАТЬ последние N для employee_id. Я хочу, чтобы формат содержал значения, которые я указал в своем примере
Я в замешательстве... Какое отношение мое предложение табличной функции имеет к
INSERT
ing?