我有一张桌子
Employees
:
员工ID | 员工矩阵 |
---|---|
1 | XCV |
2 | 香港天文台 |
我有一个
EmployeeMatricule
列表,我需要用它来从表 Employees
中删除记录,以及与其相关的表,其中一个列名称为 EmployeeId
。
查找具有 EmployeeId 列的表:
SELECT table_name
FROM all_tab_columns
WHERE column_name = 'EmployeeId' AND table_name <> 'Employees'
作为上述查询的结果,我将这些表作为输出
假设这是我的 EmployeeMatricule 列表:XCV、HKO、MXP
所以我想要每个表 EmployeeDepartment/SalaryPackage/SalaryPayroll :
SELECT *
FROM EmployeeDepartment
WHERE EmployeeId IN (
SELECT DISTINCT EmployeeId
FROM Employees
WHERE EmployeeMatricule IN ('XCV', 'HKO', 'MXP'))
SalaryPackage 和 SalaryPayroll 的查询相同。
我尝试使用光标:
DECLARE
CURSOR table_cursor IS
SELECT table_name
FROM all_tab_columns
WHERE column_name = 'EmployeeId' AND table_name <> 'Employees';
v_table_name VARCHAR2(128);
v_sql VARCHAR2(4000);
EmployeeId Employees.EmployeeId%TYPE;
BEGIN
OPEN table_cursor;
LOOP
FETCH table_cursor INTO v_table_name;
EXIT WHEN table_cursor%NOTFOUND;
v_sql := 'SELECT EmployeeId FROM ' || v_table_name ||
' WHERE EmployeeId IN (SELECT DISTINCT EmployeeId FROM employee WHERE EmployeeMatricule IN (''XCV'', ''HKO'', ''MXP''))';
DBMS_OUTPUT.PUT_LINE('Executing SELECT on table: ' || v_table_name);
FOR rec IN (EXECUTE IMMEDIATE v_sql)
LOOP
DBMS_OUTPUT.PUT_LINE('EmployeeId: ' || rec.EmployeeId);
END LOOP;
END LOOP;
CLOSE table_cursor;
END;
我当前的输出是:
在表 : EmployeeDepartment 上执行 SELECT
在表上执行 SELECT:SalaryPackage
在表上执行 SELECT:SalaryPayroll
虽然我希望返回带有 EmployeeId 的行来删除。
具体方法如下。
先看样本数据:
SQL> select table_name from user_tab_columns
2 where column_name = 'EMPLOYEEID'
3 and table_name <> 'EMPLOYEES';
TABLE_NAME
--------------------------------------------------------------------------------
EMPLOYEEDEPARTMENT
SALARYPAYROLL
SQL> select * from employeedepartment
2 where employeeid in (select employeeid from employees
3 where employeematricule in ('XCV', 'HKO', 'MXP'));
EMPLOYEEID DEPTID
---------- ------
1 Dept 1
2 Dept 2
SQL> select * From salarypayroll;
EMPLOYEEID PAYROLL
---------- ---------
2 Payroll A
SQL>
在一个过程中,您确实需要动态 SQL(因为您不知道实际使用的表名称),但您不需要
execute immediate
它来显示数据;我建议改用 refcursor。另一方面,当从这些表中删除行时,您确实需要它。
SQL> set serveroutput on;
SQL> declare
2 rc sys_refcursor;
3 l_empid employees.employeeid%type;
4 begin
5 for cur_t in (select table_name
6 from user_tab_columns
7 where column_name = 'EMPLOYEEID'
8 and table_name <> 'EMPLOYEES'
9 )
10 loop
11 open rc for 'select employeeid from ' || cur_t.table_name ||
12 ' where employeeid in (select employeeid from employees' ||
13 q'[ where employeematricule in ('XCV', 'HKO', 'MXP'))]';
14 loop
15 fetch rc into l_empid;
16 exit when rc%notfound;
17 dbms_output.put_line('Employee ID = ' || l_empid);
18
19 execute immediate 'delete from ' || cur_t.table_name || ' where employeeid = ' || l_empid;
20 end loop;
21 end loop;
22 end;
23 /
结果是
Employee ID = 1
Employee ID = 2
Employee ID = 2
PL/SQL procedure successfully completed.
数据呢?在与
employees
不同的表中删除:
SQL> select * from employees;
EMPLOYEEID EMP
---------- ---
1 XCV
2 HKO
SQL> select * From employeedepartment;
no rows selected
SQL> select * from salarypayroll;
no rows selected
SQL>