我有一个名单。
约翰,山姆,彼得,杰克我想用上面的每一个作为过滤器查询相同的sql。每个查询都会给我一个唯一的员工ID,我想用它来删除其他一些记录。
select emp_id from employee where emp_name like '%john%';
让我们说第一个查询,我得到的id为1001.所以删除查询就像是跟随。
delete from account_details where emp_id = 1001;
delete from hr_details where emp_id = 1001;
delete from pay_role_details where emp_id = 1001;
我必须重复这个以获取员工名单。伪代码就像是跟随。
var emp_list = ['john', 'jack', 'kate', 'peter', 'sam',...]
for each :employee_name in emp_list
select emp_id as :var_emp_id from employee where emp_name like '%:employee_name%';
delete from account_details where emp_id = :var_emp_id;
delete from hr_details where emp_id = :var_emp_id;
delete from pay_role_details where emp_id = :var_emp_id;
end loop
我想要一个PL-SQL查询来执行此操作。请帮忙。谢谢。
我尝试的是以下内容。
set serveroutput on;
begin
loop x in ('john','jack', 'kate') loop as :name
select emp_id as var_emp_id from employee where emp_name like '%:name%';
// delete queries
end loop;
end;
P.S。虽然根据问题,如查询可能会导致多条记录,但在实际场景中,它保证只有一条记录。为什么我使用的是在实际场景中,它是参考数字列表而不是名称。参考编号有一些其他的前文和后期文本,我的逗号分隔列表只有数字。
答案 0 :(得分:4)
也许以下内容会有所帮助:
BEGIN
FOR aName IN (SELECT 'john' AS EMP_NAME FROM DUAL
UNION ALL
SELECT 'sam' AS EMP_NAME FROM DUAL
UNION ALL
SELECT 'peter' AS EMP_NAME FROM DUAL
UNION ALL
SELECT 'jack' AS EMP_NAME FROM DUAL)
LOOP
FOR emp IN (SELECT * FROM EMPLOYEE WHERE EMP_NAME LIKE '%' || aName.EMP_NAME || '%')
LOOP
DELETE FROM ACCOUNT_DETAILS a WHERE a.EMP_ID = emp.EMP_ID;
DELETE FROM HR_DETAILS h WHERE h.EMP_ID = emp.EMP_ID;
DELETE FROM PAY_ROLE_DETAILS p WHERE p.EMP_ID = emp.EMP_ID;
DBMS_OUTPUT.PUT_LINE('Deleted data for employee with EMP_ID=' || emp.EMP_ID);
END LOOP; -- emp
END LOOP; -- aName
END;
研究这个,直到你了解它的工作原理和原因。
分享并享受。
答案 1 :(得分:1)
你真的需要一个光标吗?尽可能跳过光标以避免对大量数据的性能/内存使用不佳。
delete from account_details inner join employee on account_details.emp_id = employee.emp_id where WHERE CONTAINS(employee.emp_name, '"John" OR "Sam" OR "Max"', 1) >0;
delete from hr_details inner join employee on hr_details.emp_id = employee.emp_id where WHERE CONTAINS(employee.emp_name, '"John" OR "Sam" OR "Max"', 1) >0;
delete from pay_role_details inner join employee on pay_role_details.emp_id = employee.emp_id where WHERE CONTAINS(employee.emp_name, '"John" OR "Sam" OR "Max"', 1) >0;
答案 2 :(得分:0)
使用PL / SQL游标选择要删除的所有ID,然后循环它并在每次传递时发出DELETE语句。
有关游标的详细信息,请访问:http://www.oracle.com/technetwork/issue-archive/2013/13-mar/o23plsql-1906474.html
对于动态SQL,请参见此处:http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/dynamic.htm#LNPLS627
代码示例:
PROCEDURE delete_stuff
IS
id AS NUMBER;
CURSOR your_cursor IS
SELECT emp_id FROM employee WHERE CONTAINS(employee.emp_name, '"John" OR "Sam" OR "Max"', 1) > 0;
OPEN your_cursor;
LOOP
FETCH your_cursor INTO id;
EXIT WHEN your_cursor%NOTFOUND;
EXECUTE IMMEDIATE 'DELETE FROM account_details WHERE emp_id = :id' USING id;
EXECUTE IMMEDIATE 'DELETE FROM hr_details WHERE emp_id = :id' USING id;
EXECUTE IMMEDIATE 'DELETE FROM pay_role_details WHERE emp_id = :id' USING id;
CLOSE your_cursor;
END LOOP;
EXCEPTION
WHEN OTHERS THEN NULL;
END delete_stuff;