我的代码花费太多时间执行,有没有有效的方法来执行此操作

时间:2019-02-01 11:07:01

标签: plsql plsql-package

这里有3张桌子  1.雇员(eid,ename), 2.地址(援助,地址), 3.employee_add(eid,aid)

员工和地址有很多关系。我需要做的是清除地址表中的重复项,而不会从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;

2 个答案:

答案 0 :(得分:1)

您应该可以使用以下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;

答案 1 :(得分:0)

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

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

进入

FOR ... LOOP 
    ... 
 END LOOP;

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