Vistas actualizables: WITH CHECK OPTION

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.

16 Responses to Vistas actualizables: WITH CHECK OPTION

  1. MUY BUEN COMETARIO Y EXCELENTE LA EXPLICACION

  2. PRINZES dice:

    GRAX POR LA EXPLICACION HACE TIEMPO QUERIA ENTENDER LA FUNCION DE WITH CHECK OPTION Y AKI LO ENKONTRE GRAX…

  3. Lalo dice:

    que pasa para el caso del insert into…
    el with chech option cumple la misma funcion de controlar las restricciones ???

  4. cobacheros dice:

    gracias!!!!!

  5. cobacheros dice:

    gracias!!!!! muy buena la explicacion… mañana rendimos y teniamos esa duda :P… saludos

  6. Oscar Santos dice:

    Excelente explicación. Cómo siempre un ejemplo vale más que mil palabras.

    Saludos y Gracias!! 😉

  7. Maikel dice:

    Buen ejemplo!!

  8. Alex dice:

    Hola muy buen aporte. thank you…

  9. Guiller dice:

    Hola,

    Muy bien explicado. Gracias!

  10. delbetu dice:

    Muy bien explicado, gracias por la info!

  11. Mor TALES dice:

    Gracias, insuperable tu explicacion

  12. Abraham Concha dice:

    Excelente, he comprendido completamente lo que es una vista

  13. Sergio Grau dice:

    Gracias por la explicación.

  14. Incubux dice:

    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?

Deja un comentario