根据列和表列表获取要删除的记录列表

问题描述 投票:0回答:1

我有一张桌子

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 oracle-database oracle11g
1个回答
0
投票

具体方法如下。

先看样本数据:

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>
© www.soinside.com 2019 - 2024. All rights reserved.