CREATE VIEW

CREATE VIEW — define una nueva vista

Synopsis

CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] [ RECURSIVE ] VIEW nombre [ ( nombre_columna [, ...] ) ]
    [ WITH ( nombre_opción_vista [= valor_opción_vista] [, ... ] ) ]
    AS consulta
    [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]

Descripción

CREATE VIEW define una vista de una consulta. La vista no se materializa físicamente. En su lugar, la consulta se ejecuta cada vez que se hace referencia a la vista en una consulta.

CREATE OR REPLACE VIEW es similar, pero si ya existe una vista con el mismo nombre, se reemplaza. La nueva consulta debe generar las mismas columnas que generaba la consulta de la vista existente (es decir, los mismos nombres de columna en el mismo orden y con los mismos tipos de datos), pero puede añadir columnas adicionales al final de la lista. Los cálculos que dan lugar a las columnas de salida pueden ser completamente diferentes.

Si se proporciona un nombre de esquema (por ejemplo, CREATE VIEW miesquema.mivista ...), entonces la vista se crea en el esquema especificado. De lo contrario, se crea en el esquema actual. Las vistas temporales existen en un esquema especial, por lo que no se puede proporcionar un nombre de esquema al crear una vista temporal. El nombre de la vista debe ser diferente del nombre de cualquier otra relación (tabla, secuencia, índice, vista, vista materializada o tabla foránea) en el mismo esquema.

Parámetros

TEMPORARY o TEMP

Si se especifica, la vista se crea como una vista temporal. Las vistas temporales se eliminan automáticamente al final de la sesión actual. Las relaciones permanentes existentes con el mismo nombre no son visibles para la sesión actual mientras exista la vista temporal, a menos que se haga referencia a ellas con nombres calificados por esquema.

Si alguna de las tablas referenciadas por la vista es temporal, la vista se crea como una vista temporal (se especifique o no TEMPORARY).

RECURSIVE

Crea una vista recursiva. La sintaxis

CREATE RECURSIVE VIEW [ esquema . ] nombre_vista (nombres_columnas) AS SELECT ...;

es equivalente a

CREATE VIEW [ esquema . ] nombre_vista AS WITH RECURSIVE nombre_vista (nombres_columnas) AS (SELECT ...) SELECT nombres_columnas FROM nombre_vista;

Se debe especificar una lista de nombres de columna de la vista para una vista recursiva.

nombre

El nombre (opcionalmente calificado por esquema) de la vista que se va a crear.

nombre_columna

Una lista opcional de nombres que se utilizarán para las columnas de la vista. Si no se proporciona, los nombres de las columnas se deducen de la consulta.

WITH ( nombre_opción_vista [= valor_opción_vista] [, ... ] )

Esta cláusula especifica parámetros opcionales para una vista; se admiten los siguientes parámetros:

check_option (enum)

Este parámetro puede ser local o cascaded, y equivale a especificar WITH [ CASCADED | LOCAL ] CHECK OPTION (ver más abajo).

security_barrier (boolean)

Esto debe usarse si la vista está destinada a proporcionar seguridad a nivel de fila. Consulta Section 39.5 para obtener todos los detalles.

security_invoker (boolean)

Esta opción hace que las relaciones base subyacentes se verifiquen con los privilegios del usuario de la vista en lugar del propietario de la vista. Consulta las notas a continuación para obtener todos los detalles.

Todas las opciones anteriores se pueden cambiar en las vistas existentes mediante ALTER VIEW.

consulta

Un comando SELECT o VALUES que proporcionará las columnas y filas de la vista.

WITH [ CASCADED | LOCAL ] CHECK OPTION

Esta opción controla el comportamiento de las vistas actualizables automáticamente. Cuando se especifica esta opción, los comandos INSERT, UPDATE y MERGE en la vista se verificarán para garantizar que las nuevas filas cumplan con la condición que define la vista (es decir, se verifica que las nuevas filas sean visibles a través de la vista). Si no lo son, la actualización será rechazada. Si no se especifica CHECK OPTION, se permite que los comandos INSERT, UPDATE y MERGE en la vista creen filas que no sean visibles a través de ella. Se admiten las siguientes opciones de verificación:

LOCAL

Las nuevas filas solo se verifican contra las condiciones definidas directamente en la propia vista. No se verifica ninguna condición definida en las vistas base subyacentes (a menos que también especifiquen la opción CHECK OPTION).

CASCADED

Las nuevas filas se verifican contra las condiciones de la vista y de todas las vistas base subyacentes. Si se especifica CHECK OPTION y no se especifica ni LOCAL ni CASCADED, se asume CASCADED.

La opción CHECK OPTION no se puede utilizar con vistas RECURSIVE.

Ten en cuenta que CHECK OPTION solo se admite en vistas que son actualizables automáticamente y no tienen disparadores (triggers) INSTEAD OF ni reglas INSTEAD. Si una vista actualizable automáticamente se define sobre una vista base que tiene disparadores INSTEAD OF, entonces se puede usar LOCAL CHECK OPTION para verificar las condiciones en la vista actualizable automáticamente, pero las condiciones en la vista base con disparadores INSTEAD OF no se verificarán (una opción de verificación en cascada no se aplicará en cascada a una vista actualizable por disparador, y cualquier opción de verificación definida directamente en una vista actualizable por disparador se ignorará). Si la vista o cualquiera de sus relaciones base tiene una regla INSTEAD que hace que se reescriba el comando INSERT o UPDATE, entonces se ignorarán todas las opciones de verificación en la consulta reescrita, incluyendo cualquier verificación de vistas actualizables automáticamente definidas sobre la relación con la regla INSTEAD. MERGE no está admitido si la vista o cualquiera de sus relaciones base tiene reglas.

Notas

Utiliza la sentencia DROP VIEW to eliminar vistas.

Asegúrate de que los nombres y tipos de las columnas de la vista se asignen de la manera que deseas. Por ejemplo:

CREATE VIEW vista AS SELECT 'Hello World';

es una mala práctica porque el nombre de la columna por defecto es ?column?; además, el tipo de datos de la columna por defecto es text, lo cual podría no ser lo que deseas. Un mejor estilo para un literal de cadena en el resultado de una vista es algo como:

CREATE VIEW vista AS SELECT text 'Hello World' AS hello;

Por defecto, el acceso a las relaciones base subyacentes referenciadas en la vista está determinado por los permisos del propietario de la vista. En algunos casos, esto se puede usar para proporcionar un acceso seguro pero restringido a las tablas subyacentes. Sin embargo, no todas las vistas son seguras contra la manipulación; consulta Section 39.5 para obtener más detalles.

Si la vista tiene la propiedad security_invoker establecida en true, el acceso a las relaciones base subyacentes se determina mediante los permisos del usuario que ejecuta la consulta, en lugar del propietario de la vista. Por lo tanto, el usuario de una vista con invocador de seguridad debe tener los permisos pertinentes en la vista y en sus relaciones base subyacentes.

Si alguna de las relaciones base subyacentes es una vista con invocador de seguridad, se tratará como si se hubiera accedido a ella directamente desde la consulta original. Por lo tanto, una vista con invocador de seguridad siempre verificará sus relaciones base subyacentes utilizando los permisos del usuario actual, incluso si se accede a ella desde una vista sin la propiedad security_invoker.

Si alguna de las relaciones base subyacentes tiene habilitada la seguridad a nivel de fila, entonces, por defecto, se aplican las políticas de seguridad a nivel de fila del propietario de la vista, y el acceso a cualquier relación adicional a la que se refieran esas políticas se determina mediante los permisos del propietario de la vista. Sin embargo, si la vista tiene security_invoker establecido en true, entonces se utilizan en su lugar las políticas y permisos del usuario invocador, como si las relaciones base hubieran sido referenciadas directamente desde la consulta utilizando la vista.

Las funciones llamadas en la vista se tratan igual que si se hubieran llamado directamente desde la consulta que utiliza la vista. Por lo tanto, el usuario de una vista debe tener permisos para llamar a todas las funciones utilizadas por la vista. Las funciones en la vista se ejecutan con los privilegios del usuario que ejecuta la consulta o del propietario de la función, dependiendo de si las funciones están definidas como SECURITY INVOKER o SECURITY DEFINER. De este modo, por ejemplo, llamar a CURRENT_USER directamente en una vista siempre devolverá al usuario invocador, no al propietario de la vista. Esto no se ve afectado por la configuración de security_invoker de la vista y, por lo tanto, una vista con security_invoker establecido en false no equivale a una función SECURITY DEFINER y esos conceptos no deben confundirse.

El usuario que crea o reemplaza una vista debe tener privilegios USAGE en cualquier esquema al que se haga referencia en la consulta de la vista, para poder buscar los objetos referenciados en esos esquemas. Ten en cuenta, sin embargo, que esta búsqueda solo ocurre cuando se crea o reemplaza la vista. Por lo tanto, el usuario de la vista solo requiere el privilegio USAGE en el esquema que contiene la vista, no en los esquemas a los que se hace referencia en la consulta de la vista, incluso para una vista con invocador de seguridad.

Cuando se utiliza CREATE OR REPLACE VIEW en una vista existente, solo se cambian la regla SELECT que define la vista, además de cualquier parámetro WITH ( ... ) y su CHECK OPTION. Otras propiedades de la vista, incluyendo la propiedad, los permisos y las reglas que no son SELECT, permanecen sin cambios. Debes ser el propietario de la vista para reemplazarla (esto incluye ser miembro del rol propietario).

Vistas actualizables

Las vistas simples son actualizables automáticamente: el sistema permitirá utilizar sentencias INSERT, UPDATE, DELETE y MERGE en la vista de la misma manera que en una tabla normal. Una vista es actualizable automáticamente si cumple con todas las condiciones siguientes:

  • La vista debe tener exactamente una entrada en su lista FROM, que debe ser una tabla u otra vista actualizable.

  • La definición de la vista no debe contener cláusulas WITH, DISTINCT, GROUP BY, HAVING, LIMIT o OFFSET en el nivel superior.

  • La definición de la vista no debe contener operaciones de conjunto (UNION, INTERSECT o EXCEPT) en el nivel superior.

  • La lista de selección de la vista no debe contener agregados, funciones de ventana ni funciones que devuelvan conjuntos.

Una vista actualizable automáticamente puede contener una mezcla de columnas actualizables y no actualizables. Una columna es actualizable si es una referencia simple a una columna actualizable de la relación base subyacente; de lo contrario, la columna es de solo lectura, y se generará un error si una sentencia INSERT, UPDATE o MERGE intenta asignarle un valor.

Si la vista es actualizable automáticamente, el sistema convertirá cualquier sentencia INSERT, UPDATE, DELETE o MERGE en la vista en la sentencia correspondiente en la relación base subyacente. Las sentencias INSERT que tienen una cláusula ON CONFLICT UPDATE están completamente admitidas.

Si una vista actualizable automáticamente contiene una condición WHERE, la condición restringe qué filas de la relación base están disponibles para ser modificadas mediante sentencias UPDATE, DELETE y MERGE en la vista. Sin embargo, se permite que un UPDATE o MERGE cambie una fila de modo que ya no cumpla con la condición WHERE y, por lo tanto, ya no sea visible a través de la vista. Del mismo modo, un comando INSERT o MERGE puede insertar potencialmente filas de la relación base que no cumplan con la condición WHERE y, por lo tanto, no sean visibles a través de la vista (ON CONFLICT UPDATE puede afectar de manera similar a una fila existente no visible a través de la vista). La opción CHECK OPTION se puede usar para evitar que los comandos INSERT, UPDATE y MERGE creen filas que no sean visibles a través de la vista.

Si una vista actualizable automáticamente está marcada con la propiedad security_barrier, entonces todas las condiciones WHERE de la vista (y cualquier condición que utilice operadores marcados como LEAKPROOF) siempre se evaluarán antes de cualquier condición que haya añadido un usuario de la vista. Consulta Section 39.5 para obtener todos los detalles. Ten en cuenta que, debido a esto, las filas que finalmente no se devuelven (porque no pasan las condiciones WHERE del usuario) pueden terminar siendo bloqueadas. Se puede usar EXPLAIN para ver qué condiciones se aplican a nivel de relación (y por lo tanto no bloquean filas) y cuáles no.

Una vista más compleja que no cumple con todas estas condiciones es de solo lectura por defecto: el sistema no permitirá un INSERT, UPDATE, DELETE ni MERGE en la vista. Puedes obtener el efecto de una vista actualizable creando disparadores INSTEAD OF en la vista, los cuales deben convertir los intentos de inserción, etc. en la vista en acciones adecuadas en otras tablas. Para obtener más información, consulta CREATE TRIGGER. Otra posibilidad es crear reglas (consulta CREATE RULE), pero en la práctica los disparadores son más fáciles de entender y utilizar correctamente. También ten en cuenta que MERGE no está admitido en relaciones con reglas.

Ten en cuenta que el usuario que realiza la inserción, actualización o eliminación en la vista debe tener el privilegio correspondiente de inserción, actualización o eliminación en la vista. Además, por defecto, el propietario de la vista debe tener los privilegios correspondientes en las relaciones base subyacentes, mientras que el usuario que realiza la actualización no necesita ningún permiso en las relaciones base subyacentes (consulta Section 39.5). Sin embargo, si la vista tiene security_invoker establecido en true, el usuario que realiza la actualización, en lugar del propietario de la vista, debe tener los privilegios pertinentes en las relaciones base subyacentes.

Ejemplos

Crea una vista que consista en todas las películas de comedia:

CREATE VIEW comedies AS
    SELECT *
    FROM films
    WHERE kind = 'Comedy';

Esto creará una vista que contiene las columnas que están en la tabla film en el momento de la creación de la vista. Aunque se utilizó * para crear la vista, las columnas añadidas posteriormente a la tabla no formarán parte de ella.

Crea una vista con LOCAL CHECK OPTION:

CREATE VIEW universal_comedies AS
    SELECT *
    FROM comedies
    WHERE classification = 'U'
    WITH LOCAL CHECK OPTION;

Esto creará una vista basada en la vista comedies, que muestra solo películas con kind = 'Comedy' y classification = 'U'. Cualquier intento de INSERT o UPDATE una fila en la vista será rechazado si la nueva fila no tiene classification = 'U', pero no se verificará el género (kind) de la película.

Crea una vista con CASCADED CHECK OPTION:

CREATE VIEW pg_comedies AS
    SELECT *
    FROM comedies
    WHERE classification = 'PG'
    WITH CASCADED CHECK OPTION;

Esto creará una vista que verifica tanto el género (kind) como la clasificación (classification) de las nuevas filas.

Crea una vista con una mezcla de columnas actualizables y no actualizables:

CREATE VIEW comedies AS
    SELECT f.*,
           country_code_to_name(f.country_code) AS country,
           (SELECT avg(r.rating)
            FROM user_ratings r
            WHERE r.film_id = f.id) AS avg_rating
    FROM films f
    WHERE f.kind = 'Comedy';

Esta vista admitirá INSERT, UPDATE y DELETE. Todas las columnas de la tabla films serán actualizables, mientras que las columnas calculadas country y avg_rating serán de solo lectura.

Crea una vista recursiva que consista en los números del 1 al 100:

CREATE RECURSIVE VIEW public.nums_1_100 (n) AS
    VALUES (1)
UNION ALL
    SELECT n+1 FROM nums_1_100 WHERE n < 100;

Ten en cuenta que aunque el nombre de la vista recursiva está calificado por esquema en este CREATE, su autorreferencia interna no está calificada por esquema. Esto se debe a que el nombre de la CTE creada implícitamente no puede estar calificado por esquema.

Compatibilidad

CREATE OR REPLACE VIEW es una extensión del lenguaje de PostgreSQL. También lo es el concepto de una vista temporal. La cláusula WITH ( ... ) también es una extensión, al igual que las vistas con barrera de seguridad y las vistas con invocador de seguridad.

Consulte también

ALTER VIEW, DROP VIEW, CREATE MATERIALIZED VIEW