Мой код занимает слишком много времени для выполнения, есть ли эффективный способ сделать это
Здесь есть 3 таблицы: 1.mployee(eid,ename), 2.адрес (help, адрес), 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 ответа
Вы должны быть в состоянии сделать это, используя следующие операторы 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;
В общем случае явный курсор медленнее, чем имплицитный курсор. Вы можете попытаться преобразовать
OPEN ...
LOOP
FETCH ...
EXIT WHEN ...
...
...
END LOOP;
в
FOR ... LOOP
...
END LOOP;
иначе было бы полезно, если бы вы предоставили некоторые DDL и DML (вместе с PK, индексами и ограничениями).