La utilización de vistas es un mecanismo muy útil si se quiere filtrar, preparar o incluso encapsular la información que existe en las tablas subyacentes.
Las vistas pueden suponer un método fácil de implementar un grado de abstracción sobre cierta parte de los datos que existen en las tablas. La creación de vistas actualizables que ‘compartimenten’ los datos es algo fácil de hacer, pero sobre lo que hay que tener unas mínimas precauciones.
Veamos un caso: Tenemos una tabla y queremos implementar una regla de negocio que filtre los datos según cierto criterio.
SQL*Plus: Release 10.2.0.1.0 - Production on Mié Abr 11 12:08:57 2007 Copyright (c) 1982, 2005, Oracle. All rights reserved. Introduzca el nombre de usuario: carlos@bd01.xxxxxxxx Introduzca la contraseña: Conectado a: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bit Production With the Partitioning and Data Mining options carlos@bd01.xxxxxxxx> SELECT * FROM PRUEBA01; ID_N C_TXT ---------- ------------------------- 30 TREINTA 1 UNO 2 DOS 3 TRES 4 CUATRO 5 CINCO 21 VEINTIUNO 22 VEINTIDOS 23 VEINTITRES 24 VEINTICUATRO 25 VEINTICINCO 11 filas seleccionadas.
Un método sencillo es crear una vista que filtre los datos según el criterio requerido:
carlos@bd01.xxxxxxxx> CREATE VIEW PRUEBA01_VW AS 2> SELECT ID_N, C_TXT FROM PRUEBA01 3> WHERE ID_N <= 10; Vista creada. carlos@bd01.xxxxxxxx> SELECT * FROM PRUEBA01_VW; ID_N C_TXT ---------- ------------------------- 1 UNO 2 DOS 3 TRES 4 CUATRO 5 CINCO
Hasta aquí todo fácil. Podemos insertar filas en esa vista sin ningún problema y los datos se almacenarán en la tabla subyacente:
carlos@bd01.xxxxxxxx> INSERT INTO PRUEBA01_VW VALUES (6, 'SEIS'); 1 fila creada. carlos@bd01.xxxxxxxx> SELECT * FROM PRUEBA01_VW; ID_N C_TXT ---------- ------------------------- 1 UNO 2 DOS 3 TRES 4 CUATRO 5 CINCO 6 SEIS 6 filas seleccionadas. carlos@bd01.xxxxxxxx> SELECT * FROM PRUEBA01; ID_N C_TXT ---------- ------------------------- 30 TREINTA 1 UNO 2 DOS 3 TRES 4 CUATRO 5 CINCO 21 VEINTIUNO 22 VEINTIDOS 23 VEINTITRES 24 VEINTICUATRO 25 VEINTICINCO 6 SEIS 12 filas seleccionadas.
Pero aquí pueden empezar los problemas, porque a través de la vista se podrían hacer modificaciones a la tabla de una manera descontrolada:
carlos@bd01.xxxxxxxx> INSERT INTO PRUEBA01_VW VALUES (11,'ONCE'); 1 fila creada. carlos@bd01.xxxxxxxx> SELECT * FROM PRUEBA01_VW; ID_N C_TXT ---------- ------------------------- 1 UNO 2 DOS 3 TRES 4 CUATRO 5 CINCO 6 SEIS 6 filas seleccionadas. carlos@bd01.xxxxxxxx> SELECT * FROM PRUEBA01; ID_N C_TXT ---------- ------------------------- 30 TREINTA 1 UNO 2 DOS 3 TRES 4 CUATRO 5 CINCO 21 VEINTIUNO 22 VEINTIDOS 23 VEINTITRES 24 VEINTICUATRO 25 VEINTICINCO 6 SEIS 11 ONCE 13 filas seleccionadas.
Aquí hemos visto que se puede hacer un ‘INSERT’ ‘a ciegas’: Hemos insertado en la vista una fila que no podemos ver, pero que sí fue insertada en la tabla base. Esto da pie a que puedan hacerse operaciones que pasen inadvertidas.
Incluso más: se pueden dar errores incomprensibles:
carlos@bd01.xxxxxxxx> INSERT INTO PRUEBA01_VW VALUES (21,'VEINTIUNO'); INSERT INTO PRUEBA01_VW VALUES (21,'VEINTIUNO') * ERROR en línea 1: ORA-00001: unique constraint (CARLOS.PRUEBA01_PK) violated
En este caso y en el anterior (la inserción ‘a ciegas’ y el error) puede ocurrir que el nombre de la vista no nos dé pistas de que no se trata de una tabla ‘ordinaria’, haciendo el comportamiento más extraño a ojos de un observador.
Estos problemas se solicionarán fácilmente si utilizamos la opción ‘WITH CHECK OPTION’ en la creación de la vista. Esta opción hace que las operaciones DML sobre dicha vista pasen un control de integridad que corresponda a los criterios de definición de la propia vista:
carlos@bd01.xxxxxxxx> CREATE OR REPLACE VIEW PRUEBA01_VW AS 2> SELECT ID_N, C_TXT FROM PRUEBA01 3> WHERE ID_N <= 10 4> WITH CHECK OPTION; Vista creada. carlos@bd01.xxxxxxxx> SELECT * FROM PRUEBA01_VW; ID_N C_TXT ---------- ------------------------- 1 UNO 2 DOS 3 TRES 4 CUATRO 5 CINCO 6 SEIS 6 filas seleccionadas.
Si ahora intentamos hacer una inserción (o modificación) que salga de los criterios de definición de la vista tendremos que:
carlos@bd01.xxxxxxxx> INSERT INTO PRUEBA01_VW VALUES (12,'DOCE'); INSERT INTO PRUEBA01_VW VALUES (12,'DOCE') * ERROR en línea 1: ORA-01402: view WITH CHECK OPTION where-clause violation carlos@bd01.xxxxxxxx>
Por supuesto, esto también es válido para ‘UPDATE’:
carlos@bd01.xxxxxxxx> UPDATE PRUEBA01_VW SET ID_N=50 WHERE ID_N=1; UPDATE PRUEBA01_VW SET ID_N=50 WHERE ID_N=1 * ERROR en línea 1: ORA-01402: view WITH CHECK OPTION where-clause violation carlos@bd01.xxxxxxxx>
En resumen, si se utilizan vistas actualizables como mecanismo de ‘encapsulamiento de visibilidad de datos’ se debería siempre considerar la opción ‘WITH CHECK OPTION’ para evitar resultados no deseados de inconsistencia y reforzar además las referidas políticas de visibilidad (y más importante: de actualización) de los datos.
Saludos.
Carlos.
MUY BUEN COMETARIO Y EXCELENTE LA EXPLICACION
GRAX POR LA EXPLICACION HACE TIEMPO QUERIA ENTENDER LA FUNCION DE WITH CHECK OPTION Y AKI LO ENKONTRE GRAX…
que pasa para el caso del insert into…
el with chech option cumple la misma funcion de controlar las restricciones ???
Lalo:
No estoy muy seguro de a qué te refieres con INSERT INTO… pero sí: WITH CHECK OPTION controlará siempre las restricciones definidas para la vista.
Saludos.
Carlos.
gracias!!!!!
gracias!!!!! muy buena la explicacion… mañana rendimos y teniamos esa duda :P… saludos
Excelente explicación. Cómo siempre un ejemplo vale más que mil palabras.
Saludos y Gracias!! 😉
Buen ejemplo!!
Hola muy buen aporte. thank you…
Hola,
Muy bien explicado. Gracias!
Muy bien explicado, gracias por la info!
Gracias, insuperable tu explicacion
Excelente, he comprendido completamente lo que es una vista
Gracias por la explicación.
No entiendo, osea que con esa restricción no se podrían insertar o actualizar datos directamente a la vista y se debería hacer esas inserciones y actualizaciones a la tabla subyacente?
Pues es verdad que no lo entiendes. Es justo lo contrario.
Saludos.
Carlos.