Plsql 我的代码执行时间太长,有没有有效的方法

Plsql 我的代码执行时间太长,有没有有效的方法,plsql,plsql-package,Plsql,Plsql Package,这里有三张桌子 1.员工(eid、ename), 2.地址(援助、地址), 3.员工添加(eid,aid) employee和address之间存在多对多关系。我需要做的是清除address表中的副本,而不会丢失employee_add表中的任何数据。提前谢谢!请帮忙 DECLARE a ADDRESS.AID%TYPE; b ADDRESS.ADDRESS%TYPE; c ADDRESS.AID%TYPE; d AD

这里有三张桌子 1.员工(eid、ename), 2.地址(援助、地址), 3.员工添加(eid,aid)

employee和address之间存在多对多关系。我需要做的是清除address表中的副本,而不会丢失employee_add表中的任何数据。提前谢谢!请帮忙

   DECLARE
         a ADDRESS.AID%TYPE;
         b ADDRESS.ADDRESS%TYPE;
         c ADDRESS.AID%TYPE;
         d ADDRESS.ADDRESS%TYPE;
         CURSOR Cur1 IS
          SELECT AID,ADDRESS
          FROM ADDRESS;
          CURSOR Cur2 IS
            SELECT AID,ADDRESS
             FROM ADDRESS;
      BEGIN
        OPEN Cur1;
         LOOP
            FETCH Cur1 INTO a, b;
            EXIT WHEN Cur1%NOTFOUND;
            OPEN Cur2;
            LOOP
            FETCH Cur2 into c,d;
            IF (b=d) THEN
                IF(a!=c) THEN
                    update  employee_add set aid=a where aid=c;
                    delete from address where aid=c;
                END IF;
                END IF;
                END LOOP;
                CLOSE Cur2;
                END LOOP;
                CLOSE Cur1;

                 END;

通常,显式游标比隐式游标慢。 您可以尝试转换

OPEN ...
    LOOP 
        FETCH ... 
        EXIT WHEN ... 
        ...
        ...
    END LOOP;
进入


否则,如果您提供一些DDL和DML(以及PK、索引和约束),这会有所帮助。

您应该能够使用以下SQL语句(如果您愿意,可以将其放入PL/SQL过程中)来实现这一点,如下所示:

-- To update the employee_add tables
MERGE INTO employee_add tgt
  USING (SELECT ea.rowid rid,
                a.aid,
                a.address,
                MIN(aid) OVER (PARTITION BY address) new_aid
         FROM   address a
                INNER JOIN employee_add ea ON ea.aid = a.aid) src
  ON (tgt.rowid = src.rid)
WHEN MATCHED THEN
  UPDATE SET tgt.aid = src.new_aid
  WHERE tgt.aid != src.new_aid;

-- Delete any rows now longer in the employee_add table
DELETE FROM address
WHERE aid NOT IN (SELECT aid FROM employee_add);

-- If you need to deduplicate the employee_add table, this should do the trick:
DELETE FROM employee_add ea1
WHERE ROWID > (SELECT MIN(ROWID)
               FROM   employee_add ea2
               WHERE  ea1.eid = ea2.eid
               AND    ea1.aid = ea2.aid;

那么在employee_add表中会有重复的行?例如,如果eid=1有3个重复的地址,那么在employee_add中会有3行具有相同的eid和aid。这有意义吗,或者我们应该从employee_add中删除重复的行吗?显示每个表中的一些示例行,并告诉我们您正试图实现什么。看起来,纯SQL中的简单DML语句就是您所需要的。但是,示例数据将极大地帮助我们测试并为您提供可行的解决方案。[员工表:1--amar 2-virat 3--aaditya],,,,,,,,[地址表--101--班格洛102--班格洛103--班格洛104--帕特纳105--帕特纳106--帕特纳107--帕特纳108--普纳109--普纳]……[雇员地址表1--101 1--102 1--103 1--107 2--101 2--102 2--105 3--102 3--108]我要的是--地址表[101--班格洛104--帕特纳108--普纳]和雇员地址[1--101 1--104 2--101 2--104 3--101 3--108]我已经给出了代码,它显示了相同的结果,甚至地址表是参考下面的答案nt工作帮助这是代码,它正在工作,但没有显示我想要的我留下了重复的部分请帮助
-- To update the employee_add tables
MERGE INTO employee_add tgt
  USING (SELECT ea.rowid rid,
                a.aid,
                a.address,
                MIN(aid) OVER (PARTITION BY address) new_aid
         FROM   address a
                INNER JOIN employee_add ea ON ea.aid = a.aid) src
  ON (tgt.rowid = src.rid)
WHEN MATCHED THEN
  UPDATE SET tgt.aid = src.new_aid
  WHERE tgt.aid != src.new_aid;

-- Delete any rows now longer in the employee_add table
DELETE FROM address
WHERE aid NOT IN (SELECT aid FROM employee_add);

-- If you need to deduplicate the employee_add table, this should do the trick:
DELETE FROM employee_add ea1
WHERE ROWID > (SELECT MIN(ROWID)
               FROM   employee_add ea2
               WHERE  ea1.eid = ea2.eid
               AND    ea1.aid = ea2.aid;