La regla general es que, si puede hacerlo utilizando una única instrucción de SQL en lugar de usar PL/SQL, debería hacerlo. Por lo general será más eficiente.
Sin embargo, si necesita agregar más lógica de procedimiento (por alguna razón), puede necesitar usar PL/SQL, pero debe usar operaciones masivas en lugar de procesamiento de fila por fila. (Nota: en Oracle 10g y posterior, su bucle FOR utilizará automáticamente BULK COLLECT para buscar 100 filas a la vez; sin embargo, su instrucción de inserción se seguirá haciendo fila por fila).
p. Ej.
DECLARE
TYPE tA IS TABLE OF FOO.A%TYPE INDEX BY PLS_INTEGER;
TYPE tB IS TABLE OF FOO.B%TYPE INDEX BY PLS_INTEGER;
TYPE tC IS TABLE OF FOO.C%TYPE INDEX BY PLS_INTEGER;
rA tA;
rB tB;
rC tC;
BEGIN
SELECT * BULK COLLECT INTO rA, rB, rC FROM FOO;
-- (do some procedural logic on the data?)
FORALL i IN rA.FIRST..rA.LAST
INSERT INTO BAR(A,
B,
C)
VALUES(rA(i),
rB(i),
rC(i));
END;
Lo anterior tiene la ventaja de minimizar los cambios de contexto entre SQL y PL/SQL. Oracle 11g también tiene un mejor soporte para tablas de registros para que no tenga que tener una tabla PL/SQL separada para cada columna.
Además, si el volumen de datos es muy grande, es posible cambiar el código para procesar los datos en lotes.
FYI, no debe referirse a esto como una 'inserción masiva'. Si bien puede insertar grandes cantidades de datos, hay una función PL/SQL llamada Operaciones masivas (Inserciones masivas, Recopilación masiva), etc. – moleboy
Y para agregar a la referencia de operaciones masivas, debe considerar eso arriba de las otras dos para operaciones de datos grandes o en curso, operaciones de inserción regulares. Las inserciones masivas pueden producir tremendas mejoras en el rendimiento sobre inserciones simples en los ejemplos dados. – DCookie