CREATE VIEW — define una nueva vista
CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] [ RECURSIVE ] VIEWnombre[ (nombre_columna[, ...] ) ] [ WITH (nombre_opción_vista[=valor_opción_vista] [, ... ] ) ] ASconsulta[ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
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.
TEMPORARY o TEMPSi 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_vistaAS WITH RECURSIVEnombre_vista(nombres_columnas) AS (SELECT...) SELECTnombres_columnasFROMnombre_vista;
Se debe especificar una lista de nombres de columna de la vista para una vista recursiva.
nombreEl nombre (opcionalmente calificado por esquema) de la vista que se va a crear.
nombre_columnaUna 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.
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).
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.
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.
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.