Oracle PL/SQL:如何删除一行,然后使用管道将其输出?
我有一个包裹:Oracle PL/SQL:如何删除一行,然后使用管道将其输出?,sql,oracle,plsql,dml,Sql,Oracle,Plsql,Dml,我有一个包裹: CREATE OR REPLACE PACKAGE pkg_location IS TYPE dep_row IS RECORD (id departments.department_id%TYPE, name departments.department_name%TYPE); TYPE dep_table IS TABLE OF dep_row; FUNCTION drop_departments (v_city_title IN VARCHAR2)
CREATE OR REPLACE PACKAGE pkg_location IS
TYPE dep_row IS RECORD (id departments.department_id%TYPE, name departments.department_name%TYPE);
TYPE dep_table IS TABLE OF dep_row;
FUNCTION drop_departments (v_city_title IN VARCHAR2) RETURN dep_table PIPELINED;
END pkg_location;
我需要实现drop\u departments
功能,该功能通过city
从departments
表中删除行,并使用管道输出删除的部门数据
但我真的不知道从哪里开始。你能帮帮我吗
表结构:
DEPARTMENTS: DEPARTMENT_ID (NUMBER) | DEPARTMENT_NAME (VARCHAR 40) | LOCATION_ID (NUMBER)
LOCATIONS: LOCATION_ID (NUMBER) | CITY (VARCHAR 40)
您需要3个步骤:
- 将要删除的所有记录保存到与函数类型相同的本地表中
- 删除记录
- 返回您保存的集合(不必使用管道连接)
自治事务中删除记录
参见下面的3个示例
insert into departments(id , department_id , department_name , city_title ) values(1, 1, '1', 'City-1');
insert into departments(id , department_id , department_name , city_title ) values(2, 2, '2', 'City-1');
insert into departments(id , department_id , department_name , city_title ) values(3, 2, '3', 'City-2');
带有管道的示例1
CREATE OR REPLACE PACKAGE BODY pkg_location IS
FUNCTION drop_departments (v_city_title IN VARCHAR2) RETURN dep_table PIPELINED
is
tblResult dep_table;
begin
--delete the records and save deleted records
delete from departments
where city_title = v_city_title
RETURNING department_id, department_name
BULK COLLECT INTO tblResult;
--return list of deleted records
for i in tblResult.FIRST .. tblResult.LAST loop
pipe row (tblResult(i));
end loop;
end;
END pkg_location;
但是你不能像这样使用smth
从表中选择*(包装位置。放置部门('City-1'))
样本2-我已移除管道
CREATE OR REPLACE PACKAGE BODY pkg_location IS
FUNCTION drop_departments (v_city_title IN VARCHAR2) RETURN dep_table
is
tblResult dep_table;
begin
--delete the records and save deleted records
delete from departments
where city_title = v_city_title
RETURNING department_id, department_name
BULK COLLECT INTO tblResult;
--return list of deleted records
return tblResult;
end;
END pkg_location;
现在您可以这样使用该函数:
declare
tbl pkg_location.dep_table;
begin
tbl := pkg_location.drop_departments('City-1');
for i in tbl.first .. tbl.last loop
dbms_output.put_line(tbl(i).name);
end loop;
end;
输出将为1和2
示例3-使用自主交易
CREATE OR REPLACE PACKAGE BODY pkg_location IS
FUNCTION drop_departments (v_city_title IN VARCHAR2) RETURN dep_table PIPELINED
is
--it let you use the function in select * from table(f)
PRAGMA AUTONOMOUS_TRANSACTION;
tblResult dep_table;
begin
--delete the records and save deleted records
delete from departments
where city_title = v_city_title
returning department_id, department_name
bulk collect into tblResult;
--you must do the commit before pipe row ()
commit;
--return list of deleted records
for i in tblResult.FIRST .. tblResult.LAST loop
pipe row (tblResult(i));
end loop;
end;
END pkg_location;
现在你可以使用
select * from table(pkg_location.drop_departments('City-1'))
结果将是:
1 1 1
2 2 2
删除之前的选择是不必要的,并且可能存在并发问题。您可以使用
DELETE departments WHERE city\u title=v\u city\u title RETURNING department\u id,department\u name BULK COLLECT to tblResult将删除的记录输出到集合中代码>流水线版本没有问题,它也可以使用自治事务。您只需要在管道行之前发出commit,因为这会生成一个值,并将函数保留到需要下一条记录为止,并且必须在保留函数作用域之前提交/回滚自治事务。但在这种情况下,返回集合的非管道方法是最好的。这是最少的代码量,您可以为所有已删除的记录分配内存,因此迭代并生成固定集合是没有意义的。