Bueno, en mi opinión, lo primero que hay que hacer es reformular la pregunta y cambiarla por la siguiente: ¿una sentencia SELECT necesita crear o leer segmentos de rollback?
En PL/SQL,
No obstante, este uso de los segmentos de rollback no va a causar nunca por sí solo un error como el antes mencionado (ORA-01650 Unable to extend rollback segment... u ORA-01651 Unable to extend undo segment... ). Sin embargo, sí que puede provocar un error del tipo "ORA-01555 Snapshot too old".
Para que una sentencia SELECT pueda generar los errores ORA-01650 u ORA-01651, es necesario que esté generando segmentos de rollback y los motivos pueden ser los siguientes:
- La sentencia SELECT contiene la cláusula FOR UPDATE.
- La funcionalidad de auditoría está habilitada.
- La sentencia SELECT invoca a algún tipo de transacción que escribe en la base de datos Oracle.
Lo más corriente es que la causa sea que la sentencia SELECT contenga una cláusula FOR UPDATE, cuando esto ocurre la base de datos Oracle bloquea todos los registros necesarios antes de que la sentencia SELECT empiece a devolver resultados, y bloquear un registro en la base de datos Oracle implica modificar un bloque de la base de datos para registrar dicho bloqueo. Por otro lado, cada vez que se modifica un bloque de la base de datos, se necesita generar un undo para esa operación.
SQL> SELECT used_ublk FROM v$transaction No rows selected SQL> BEGIN 2 FOR cursor IN ( 3 SELECT * FROM nombre_tabla 4 FOR UPDATE) 5 LOOP null; 6 END LOOP; 7 END; 10 / PL/SQL procedure successfully completed. SQL> SELECT used_ublk FROM v$transaction USED_UBLK --------- 932 SQL> COMMIT;
Según queríamos confirmar, podemos ver que la ejecución de la sentencia SELECT FOR UPDATE ha generado 932 bloques de undo (tened en cuenta que nombre_tabla debe ser una tabla que exista en vuestra base de datos Oracle).