UPDATE con JOIN en ORACLE
- Inicie sesión o regístrese para enviar comentarios
Supongamos que queremos actualizar en nuestra bbdd ORACLE el campo de costes de la tabla de hechos FAC_TABLE con el coste unitario de nuestra tabla de COSTES.
Podemos hacerlo de dos maneras:
1. (Lenta, pero si es para pocos datos o para lanzarlo esporádicamente nos puede valer)
update FAC_TABLE ft
set COSTE_UNITARIO = (select distinct COSTE_UNITARIO from COSTES ct
where (ft.id_articulo = ct.id_articulo);
2. (la mejor manera es esta, y el rendimimento es óptimo si tiene constraints)
UPDATE (
SELECT
ft.COSTE_UNITARIO AS old_coste,
ct.COSTE_UNITARIO AS new_coste
FROM FAC_TABLE ft
INNER JOIN COSTES ct ON ft.id_articulo = ct.id_articulo)
)
SET old_coste = new_coste;
Para que esta segunda oción funcione necesitamos tener UNIQUE or PRIMARY KEY constraint en ct.id_articulo.
Si no tienes esta constraint, puedes utilizar el hint /*+BYPASS_UJVC*/ después de la palabra UPDATE
(bypass update join view constraint).
El rendimiento aumenta si tenemos la constraint pero aún sin ella debe correr mucho más que la primera opción.
Espero que os ayude.
Héctor Minguet.
He tenido la oportunidad de probar este tipo de update con tablas grandes, de varios millones de registros, y realmente funciona como comentas.
He lanzado un update con la primera opción y he decidido cancelarlo cuando he visto que comenzaba a afectar negativamente al rendimiento de la base de datos. El tiempo estimado que me daba la consola de Enterprise Manager para terminar era de 1 hora y media.
Después de cancelar he probado la segunda opción y me he encontrado con el error ORA-01779 porque no tenía una clave única definida sobre el campo de la tabla con la que hacía la join. Como la tabla era demasiado grande para crear un índice único sin estudiarlo primero, he probado la opción de incluir el hint /*+BYPASS_UJVC*/ (para hacer esto hay que asegurarse antes de que la correspondencia es realmente de 1:1, si no podemos obtener resultados inesperados), y el update se ha realizado correctamente en menos de 15 minutos, una diferencia considerable.
Ahora a ver si alguien se anima y nos cuenta la mejora que se obtiene con la segunda opción, pero creando una clave única en la tabla 'enlazada', y sin utilizar el hint.
Hola se agradece este bypass.
Justamente tenía que actualizar unas tablas que tenian correlativos repetidos y tenian que ser secuenciales, realicé una tabla temporal y despues aplicar un update. De igual forma tenia que hacer un procedimiento almacenado pero en fin... con este bypass, todo bien.
El tiempo de respuesta en la actualizacion el descuebe GRACIAS!!!
gracias.
atte.
Maricela de CHILE
Gracias.
Lo utilice para una actualizacion de varios campos y se comporto de maravilla.
Utilice un script con este hint /*+BYPASS_UJVC*/ y funciona una muy bien... Bajo un script de 9 hs a 6 segungos....
Pero cuando lo quiero utilizar dentro de un Package aparece un error "PL/SQL: ORA-01031: Insufficient privileges"
¿ALGUIEN PUEDE AYUDARME CON ESTE TEMA?
DESDE YA MUCHAS GRACIAS.
Bueno lo mas probable es que sea esto, mira una cosa son los permisos que tienes tu o tu usario y otra los permisos que tiene el paquete por ejemplo digamos que tu tienes el usuario au0001 y cuando corres esto si puedes hacerlo debido a tus permisos, pero cuando pones esto dentro del paquete que esta en el esquema au0002 y dicho esquema no tiene esos priviliegios, pues es claro que te truena aun si tu como usuario au0001 si tengas el permiso y seas tu el que corre el paquete , el paquete truena por ser el o su esquema mejor dicho el que no tiene los permisos.
Hola intente hacerlo de las dos maneras, el update tradicional y con el hint, con el primero se tarda bastante, lo cancele, con el segundo me marca el error ORA-01031 - Insufficient privileges, lo estoy haciendo en el mismo esquema, la tabla de la que quiero actualizar tiene llave unique en el campo que uso para unir con la tabla que tiene la información ¿A que se debe que con uno no me marque el error y con el segundo si?
¡¡¡ UPS !!! Perdón. Gracias por la ayuda.
Contenido relacionado
-
El error ORA-30926 suele producirse cuando se realizan operaciones Merge, y lo normal es que nos deje algo descolocados, ya que la descripción del mismo no da demasiada información sobre lo que está pasando: ORA-30926: unable to get a...
-
L´error ORA-30926 sol produir quan es realitzen operacions Merge, i el normal és que ens deixi una mica descol·locats, ja que la descripció del mateix no dóna massa informació sobre el que està passant: ORA-...
-
En muchas ocasiones, especialmente en procesos ETL o de carga de datos para un data warehouse, por ejemplo, interesa hacer en una sola sentencia o en un solo paso la comprobación de si un registro existe, y si existe actualizarlo, y si no insertarlo. A...
