21.2. Sintaxis de CREATE VIEW

MySQL 5.0

21.2. Sintaxis de CREATE VIEW

CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
    VIEW  [()]
    AS 
    [WITH [CASCADED | LOCAL] CHECK OPTION]

Esta sentencia crea una vista nueva o reemplaza una existente si se incluye la cláusula . La es una sentencia que proporciona la definición de la vista. Puede estar dirigida a tablas de la base o a otras vistas.

Se requiere que posea el permiso para la vista, y algún privilegio en cada columna seleccionada por la sentencia . Para columnas incluidas en otra parte de la sentencia debe poseer el privilegio . Si está presente la cláusula , también deberá tenerse el privilegio para la vista.

Toda vista pertenece a una base de datos. Por defecto, las vistas se crean en la base de datos actual. Pera crear una vista en una base de datos específica, indíquela con al momento de crearla.

        mysql> CREATE VIEW test.v AS SELECT * FROM t;
    

Las tablas y las vistas comparten el mismo espacio de nombres en la base de datos, por eso, una base de datos no puede contener una tabla y una vista con el mismo nombre.

Al igual que las tablas, las vistas no pueden tener nombres de columnas duplicados. Por defecto, los nombres de las columnas devueltos por la sentencia se usan para las columnas de la vista . Para dar explícitamente un nombre a las columnas de la vista utilice la clásula para indicar una lista de nombres separados con comas. La cantidad de nombres indicados en debe ser igual a la cantidad de columnas devueltas por la sentencia .

Las columnas devueltas por la sentencia pueden ser simples referencias a columnas de la tabla, pero tambien pueden ser expresiones conteniendo funciones, constantes, operadores, etc.

Los nombres de tablas o vistas sin calificar en la sentencia se interpretan como pertenecientes a la base de datos actual. Una vista puede hacer referencia a tablas o vistas en otras bases de datos precediendo el nombre de la tabla o vista con el nombre de la base de datos apropiada.

Las vistas pueden crearse a partir de varios tipos de sentencias . Pueden hacer referencia a tablas o a otras vistas. Pueden usar combinaciones, , y subconsultas. El inclusive no necesita hacer referencia a otras tablas. En el siguiente ejemplo se define una vista que selecciona dos columnas de otra tabla, así como una expresión calculada a partir de ellas:

        mysql> CREATE TABLE t (qty INT, price INT);
        mysql> INSERT INTO t VALUES(3, 50);
        mysql> CREATE VIEW v AS SELECT qty, price, qty*price AS value FROM t;
        mysql> SELECT * FROM v;
        +------+-------+-------+
        | qty  | price | value |
        +------+-------+-------+
        |    3 |    50 |   150 |
        +------+-------+-------+
    

La definición de una vista está sujeta a las siguientes limitaciones:

  • La sentencia no puede contener una subconsulta en su cláusula .

  • La sentencia no puede hacer referencia a variables del sistema o del usuario.

  • La sentencia no puede hacer referencia a parámetros de sentencia preparados.

  • Dentro de una rutina almacenada, la definición no puede hacer referencia a parámetros de la rutina o a variables locales.

  • Cualquier tabla o vista referenciada por la definición debe existir. Sin embargo, es posible que después de crear una vista, se elimine alguna tabla o vista a la que se hace referencia. Para comprobar la definición de una vista en busca de problemas de este tipo, utilice la sentencia .

  • La definición no puede hacer referencia a una tabla , y tampoco se puede crear una vista .

  • Las tablas mencionadas en la definición de la vista deben existir siempre.

  • No se puede asociar un disparador con una vista.

En la definición de una vista está permitido , pero es ignorado si se seleccionan columnas de una vista que tiene su propio .

Con respecto a otras opciones o cláusulas incluidas en la definición, las mismas se agregan a las opciones o cláusulas de cualquier sentencia que haga referencia a la vista creada, pero el efecto es indefinido. Por ejemplo, si la definición de una vista incluye una cláusula , y se hace una selección desde la vista utilizando una sentencia que tiene su propia cláusula , no está definido cuál se aplicará. El mismo principio se extiende a otras opciones como , , o que se ubican a continuación de la palabra reservada , y a cláusulas como , , , y .

Si se crea una vista y luego se modifica el entorno de proceso de la consulta a traves de la modificación de variables del sistema, puede afectar los resultados devueltos por la vista:

mysql> CREATE VIEW v AS SELECT CHARSET(CHAR(65)), COLLATION(CHAR(65));
Query OK, 0 rows affected (0.00 sec)

mysql> SET NAMES 'latin1';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM v;
+-------------------+---------------------+
| CHARSET(CHAR(65)) | COLLATION(CHAR(65)) |
+-------------------+---------------------+
| latin1            | latin1_swedish_ci   |
+-------------------+---------------------+
1 row in set (0.00 sec)

mysql> SET NAMES 'utf8';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM v;
+-------------------+---------------------+
| CHARSET(CHAR(65)) | COLLATION(CHAR(65)) |
+-------------------+---------------------+
| utf8              | utf8_general_ci     |
+-------------------+---------------------+
1 row in set (0.00 sec)

La cláusula opcional es una extensión de MySQL al SQL estándar. puede tomar tres valores: , , o . El algoritmo por defecto es si no se encuentra presente la cláusula . El algoritmo afecta la manera en que MySQL procesa la vista.

Para , el texto de una sentencia que haga referencia a la vista y la definición de la vista son mezclados de forma que parte de la definición de la vista reemplaza las partes correspondientes de la consulta.

Para , los resultados devueltos por la vista son colocados en una tabla temporal, la cual es luego utilizada para ejecutar la sentencia.

Para , MySQL determina el algoritmo que utilizará. En ese caso se prefiere por sobre si es posible, ya que por lo general es más eficiente y porque la vista no puede ser actualizable si se emplea una tabla temporal.

Una razón para elegir explícitamente es que los bloqueos en tablas subyacentes pueden ser liberados despues que la tabla temporal fue creada, y antes de que sea usada para terminar el procesamiento de la sentencia. Esto podría resultar en una liberación del bloqueo más rápida que en el algoritmo , de modo que otros clientes que utilicen la vista no estarán bloqueados mucho tiempo.

El algoritmo de una vista puede ser en tres situaciones:

  • No se encuentra presente una cláusula en la sentencia .

  • La sentencia tiene explícitamente una cláusula .

  • Se especificó para una vista que solamente puede ser procesada usando una tabla temporal. En este caso, MySQL emite una advertencia y establece el algoritmo en .

Como se dijo anteriormente, provoca que las partes correspondientes de la definición de la vista se combinen dentro de la sentencia que hace referencia a la vista. El siguiente ejemplo muestra brevemente cómo funciona el algoritmo . El ejemplo asume que hay una vista con esta definición:

CREATE ALGORITHM = MERGE VIEW v_merge (vc1, vc2) AS
SELECT c1, c2 FROM t WHERE c3 > 100;

Ejemplo 1: Suponiendo que se utilice esta sentencia:

SELECT * FROM v_merge;

MySQL la gestiona del siguiente modo:

  • se convierte en

  • se convierte en , que corresponden a

  • Se agrega la cláusula de la vista

La sentencia ejecutada resulta ser:

SELECT c1, c2 FROM t WHERE c3 > 100;

Ejemplo 2: Suponiendo que se utilice esta sentencia:

SELECT * FROM v_merge WHERE vc1 < 100;

Esta sentencia se gestiona en forma similar a la anterior, a excepción de que se convierte en y la cláusula de la vista se agrega a la cláusula de la sentencia empleando un conector (y se agregan paréntesis para asegurarse que las partes de la cláusula se ejecutarán en el orden de precedencia correcto). La sentencia ejecutada resulta ser:

SELECT c1, c2 FROM t WHERE (c3 > 100) AND (c1 < 100);

Necesariamente, la sentencia a ejecutar tiene una cláusula con esta forma:

WHERE (WHERE de la sentencia) AND (WHERE de la vista)

El algoritmo necesita una relación uno-a-uno entre los registros de la vista y los registros de la tabla subyacente. Si esta relación no se sostiene, debe emplear una tabla temporal en su lugar. No se tendrá una relación uno-a-uno si la vista contiene cualquiera de estos elementos:

  • Funciones agregadas (, , , , etcétera)

  • o

  • Hace referencia solamente a valores literales (en tal caso, no hay una tabla subyacente)

Algunas vistas son actualizables. Esto significa que se las puede emplear en sentencias como , , o para actualizar el contenido de la tabla subyacente. Para que una vista sea actualizable, debe haber una relación uno-a-uno entre los registros de la vista y los registros de la tabla subyacente. Hay otros elementos que impiden que una vista sea actualizable. Más específicamente, una vista no será actualizable si contiene:

  • Funciones agregadas (, , , , etcétera)

  • o

  • Una subconsulta en la lista de columnas del SELECT

  • Join

  • Una vista no actualizable en la cláusula

  • Una subconsulta en la cláusula que hace referencia a una tabla en la cláusula

  • Hace referencia solamente a valores literales (en tal caso no hay una) tabla subyacenta para actualizar.

  • (utilizar una tabla temporal siempre resulta en una vista no actualizable)

Con respecto a la posibilidad de agregar registros mediante sentencias , es necesario que las columnas de la vista actualizable también cumplan los siguientes requisitos adicionales:

  • No debe haber nombres duplicados entre las columnas de la vista.

  • La vista debe contemplar todas las columnas de la tabla en la base de datos que no tengan indicado un valor por defecto.

  • Las columnas de la vista deben ser referencias a columnas simples y no columnas derivadas. Una columna derivada es una que deriva de una expresión. Estos son algunos ejemplos de columnas derivadas:

    3.14159
    col1 + 3
    UPPER(col2)
    col3 / col4
    ()
    

No puede insertar registros en una vista conteniendo una combinación de columnas simples y derivadas, pero puede actualizarla si actualiza únicamente las columnas no derivadas. Considere esta vista:

CREATE VIEW v AS SELECT col1, 1 AS col2 FROM t;

En esta vista no pueden agregarse registros porque es derivada de una expresión. Pero será actualizable si no intenta actualizar . Esta actualización es posible:

UPDATE v SET col1 = 0;

Esta actualización no es posible porque se intenta realizar sobre una columna derivada:

UPDATE v SET col2 = 0;

A veces, es posible que una vista compuesta por múltiples tablas sea actualizable, asumiendo que es procesada con el algoritmo . Para que esto funcione, la vista debe usar inner join (no outer join o ). Además, solamente puede actualizarse una tabla de la definición de la vista, de forma que la cláusula debe contener columnas de sólo una tabla de la vista. Las vistas que utilizan no se pueden actualizar aunque teóricamente fuese posible hacerlo, debido a que en la implementación se emplean tablas temporales para procesarlas.

En vistas compuestas por múltiples tablas, funcionará si se aplica sobre una única tabla. no está soportado.

La cláusula puede utilizarse en una vista actualizable para evitar inserciones o actualizaciones excepto en los registros en que la cláusula de la se evalúe como true.

En la cláusula de una vista actualizable, las palabras reservadas y determinan el alcance de la verificación cuando la vista está definida en términos de otras vistas. restringe el sólo a la vista que está siendo definida. provoca que las vistas subyacentes también sean verificadas. Si no se indica, el valor por defecto es . Considere las siguientes definiciones de tabla y vistas:

mysql> CREATE TABLE t1 (a INT);
mysql> CREATE VIEW v1 AS SELECT * FROM t1 WHERE a < 2
    -> WITH CHECK OPTION;
mysql> CREATE VIEW v2 AS SELECT * FROM v1 WHERE a > 0
    -> WITH LOCAL CHECK OPTION;
mysql> CREATE VIEW v3 AS SELECT * FROM v1 WHERE a > 0
    -> WITH CASCADED CHECK OPTION;

Las vistas y estan definidas en términos de otra vista, . emplea check option , por lo que las inserciones sólo atraviesan la verificación de . emplea check option de modo que las inserciones no solamente atraviesan su propia verificación sino tambien las de las vistas subyacentes. Las siguientes sentencias demuestran las diferencias:

ql> INSERT INTO v2 VALUES (2);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO v3 VALUES (2);
ERROR 1369 (HY000): CHECK OPTION failed 'test.v3'

La posibilidad de actualización de las vistas puede verse afectada por el valor de la variable del sistema . Consulte Sección 5.3.3, “Variables de sistema del servidor”.

La sentencia fue introducida en MySQL 5.0.1. La cláusula fue implementada en MySQL 5.0.2.

contiene una tabla de la cual puede obtenerse información sobre los objetos de las vistas. Consulte Sección 22.1.15, “La tabla .