CREATE VIEW

CREATE VIEW — define uma nova visão

Sinopse

CREATE [ OR REPLACE ] tipo_de_visão VIEW nome [ ( nome_da_coluna [, ...] ) ]
    [ WITH ( nome_da_opção_da_visão [= valor_da_opção_da_visão] [, ... ] ) ]
    AS consulta
    [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]

onde tipo_de_visão pode ser:

[ TEMP | TEMPORARY ] [ RECURSIVE ]

Descrição

O comando CREATE VIEW define a visão de uma consulta. A visão não é materializada fisicamente. Em vez disso, a consulta é executada sempre que a visão é referenciada em uma consulta.

O comando CREATE OR REPLACE VIEW é semelhante, mas se já existir uma visão com o mesmo nome, ela será substituída. A nova consulta deve gerar as mesmas colunas geradas pela consulta da visão existente (ou seja, os mesmos nomes de coluna na mesma ordem e com os mesmos tipos de dados), mas podem ser adicionadas colunas no final da lista. Os cálculos que dão origem às colunas de saída podem ser completamente diferentes.

Se for fornecido o nome do esquema (por exemplo, CREATE VIEW meu_esquema.minha_visão ...), então a visão será criada no esquema especificado. Caso contrário, será criada no esquema corrente. As visões temporárias existem em um esquema especial, portanto, não pode ser fornecido o nome do esquema ao criar uma visão temporária. O nome da visão deve ser diferente do nome de qualquer outra relação (tabela, sequência, índice, visão, visão materializada ou tabela estrangeira) no mesmo esquema.

Parâmetros

TEMPORARY ou TEMP

Se especificado, a visão é criada como uma visão temporária. As visões temporárias são excluídas automaticamente no final da sessão. As relações permanentes existentes com o mesmo nome não serão visíveis para a sessão corrente enquanto a visão temporária existir, a menos que sejam referenciadas com nomes qualificados pelo esquema.

Se alguma das tabelas referenciadas pela visão for temporária, a visão será criada como visão temporária (se TEMPORARY for especificado ou não).

RECURSIVE

Cria uma visão recursiva. A sintaxe

CREATE RECURSIVE VIEW [ esquema . ] nome_da_visão (nomes_das_colunas)
    AS SELECT ...;

é equivalente a

CREATE VIEW [ esquema . ] nome_da_visão
    AS WITH RECURSIVE nome_da_visão (nomes_das_colunas)
    AS (SELECT ...)
        SELECT nomes_das_colunas
        FROM nome_da_visão;

Deve ser especificada uma lista de nomes de colunas de visão para uma visão recursiva.

nome

O nome (opcionalmente qualificado pelo esquema) da visão a ser criada.

nome_da_coluna

Uma lista opcional dos nomes a serem usados para as colunas da visão. Se não forem fornecidos, os nomes das colunas serão deduzidos da consulta.

WITH ( nome_da_opção_da_visão [= valor_da_opção_da_visão] [, ... ] )

Esta cláusula especifica parâmetros opcionais para uma visão; os seguintes parâmetros têm suporte:

check_option (enum)

Este parâmetro pode ser tanto local quanto cascaded, e é equivalente a especificar WITH [ CASCADED | LOCAL ] CHECK OPTION (veja abaixo). Esta opção pode ser alterada em visões existentes usando o comando ALTER VIEW.

security_barrier (boolean)

Deve ser usado se a visão se destinar a fornecer segurança no nível de linha. Veja Regras e privilégios para obter detalhes completos.

security_invoker (boolean)

Esta opção faz com que as relações base subjacentes sejam verificadas em relação aos privilégios do usuário da visão, em vez do dono da visão. Veja as notas abaixo para obter detalhes completos.

Todas as opções acima podem ser alteradas em visões existentes usando ALTER VIEW.

consulta

O comando SELECT ou VALUES que vai produzir as colunas e linhas da visão.

WITH [ CASCADED | LOCAL ] CHECK OPTION

Esta opção controla o comportamento das visões que podem ser atualizadas automaticamente. Quando esta opção é especificada, os comandos INSERT, UPDATE e MERGE na visão serão verificados para garantir que as novas linhas satisfaçam a condição que define a visão (ou seja, as novas linhas são verificadas para garantir que estejam visíveis na visão). Se não estiverem, a atualização será rejeitada. Se não for especificada a opção CHECK OPTION, os comandos INSERT, UPDATE e MERGE na visão poderão criar linhas que não serão visíveis através da própria visão. As seguintes opções de verificação têm suporte:

LOCAL

As novas linhas são verificadas apenas nas condições definidas diretamente na própria visão. Quaisquer condições definidas nas visões base subjacentes não são verificadas (a menos que elas também especifiquem CHECK OPTION).

CASCADED

As novas linhas são verificadas em relação às condições da visão, e de todas as visões base subjacentes. Se for especificado CHECK OPTION, e nem LOCAL ou CASCADED fores especificados, então é assumido CASCADED.

A opção CHECK OPTION não deve ser usada nas visões RECURSIVE.

Note que a opção CHECK OPTION só tem suporte nas visões automaticamente atualizáveis e sem gatilhos INSTEAD OF ou regras INSTEAD. Se for definida uma visão atualizável automaticamente sobre uma visão base que possui gatilhos INSTEAD OF, então poderá ser usado LOCAL CHECK OPTION para verificar as condições na visão automaticamente atualizável, mas as condições na visão base com gatilhos INSTEAD OF não serão verificadas (uma opção de verificação em cascata não será reduzida a uma visão atualizável por gatilho, e quaisquer opções de verificação definidas diretamente em uma visão atualizável por gatilho serão ignoradas). Se a visão ou qualquer uma de suas relações base tiver uma regra INSTEAD que cause o comando INSERT ou UPDATE ser reescrito, então todas as opções de verificação serão ignoradas na consulta reescrita, incluindo quaisquer verificações de visões automaticamente atualizáveis definidas no topo da relação com a regra INSTEAD. O comando MERGE não terá suporte quando a visão, ou qualquer uma de suas relações base, tiver regras.

Notas

Deve ser usado o comando DROP VIEW para remover as visões.

Deve-se cuidar para que os nomes e tipos de dados das colunas da visão sejam atribuídos da maneira desejada. Por exemplo:

CREATE VIEW vista AS SELECT 'Hello World';

é uma forma ruim, porque o nome da coluna fica sendo ?column? por padrão; além disso, o tipo de dados da coluna fica sendo text por padrão, que pode não ser o desejado. Um estilo melhor para um literal de cadeia de caracteres no resultado de uma visão seria algo como:

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

Por padrão, o acesso às relações base subjacentes referenciadas na visão é determinado pelas permissões do dono da visão. Em alguns casos, isto pode ser usado para fornecer acesso seguro, porém restrito, às tabelas subjacentes. No entanto, nem todas as visões são seguras contra adulteração; veja Regras e privilégios para obter detalhes.

Se a visão tiver a propriedade security_invoker definida como true, o acesso às relações base subjacentes será determinado pelas permissões do usuário que executa a consulta, e não pelas permissões do dono da visão. Assim, o usuário de uma visão com invocação de segurança deve ter as permissões apropriadas na visão e em suas relações base subjacentes.

Se alguma das relações base subjacentes for uma visão com invocação de segurança, ela será tratada como se tivesse sido acessada diretamente pela consulta original. Assim, uma visão com invocação de segurança sempre irá verificar suas relações de base subjacentes usando as permissões do usuário corrente, mesmo que seja acessada a partir de uma visão sem a propriedade security_invoker.

Se alguma das relações de base subjacentes tiver Políticas de segurança de linha ativado, então, por padrão, as políticas de segurança no nível de linha do dono da visão são aplicadas, e o acesso a quaisquer relações adicionais mencionadas por estas políticas é determinado pelas permissões do dono da visão. Entretanto, se a visão tiver security_invoker definido como true, então as políticas e permissões do usuário que invocou o recurso são utilizadas, como se as relações base tivessem sido referenciadas diretamente pela consulta usando a visão.

As funções chamadas na visão são tratadas da mesma forma como se tivessem sido chamadas diretamente pela consulta usando a visão. Portanto, o usuário de uma visão deve ter permissões para chamar todas as funções usadas pela visão. As funções na visão são executadas com os privilégios do usuário que executa a consulta ou do dono da função, dependendo se as funções estão definidas como SECURITY INVOKER ou SECURITY DEFINER. Assim, por exemplo, chamar CURRENT_USER diretamente em uma visão, sempre retornará o usuário que a invocou, não o dono da visão. Isto não é afetado pela definição de security_invoker da visão, portanto uma visão definida com security_invoker como false não é equivalente a uma função SECURITY DEFINER, e estes conceitos não devem ser confundidos.

O usuário que cria ou substitui uma visão deve ter privilégios USAGE em quaisquer esquemas referenciados na consulta da visão, para poder procurar os objetos referenciados nesses esquemas. Note, no entanto, que esta pesquisa só ocorre quando a visão é criada ou substituída. Portanto, o usuário da visão precisa ter apenas o privilégio USAGE no esquema que contém a visão, e não nos esquemas referenciados na consulta da visão, mesmo para uma visão de invocação de segurança.

Quando é usado o comando CREATE OR REPLACE VIEW em uma visão existente, somente a regra SELECT que define a visão, mais quaisquer parâmetros WITH ( ... ) e suas CHECK OPTION são mudadas. Outras propriedades da visão, incluindo propriedade, permissões e regras não-SELECT, permanecem inalteradas. É necessário ser o dono da visão para substituí-la (isto inclui ser membro da função de banco de dados que é a dona).

Visões atualizáveis

As visões simples são atualizáveis automaticamente: o sistema permitirá o uso dos comandos INSERT, UPDATE, DELETE e MERGE na visão da mesma forma que em uma tabela normal. A visão será automaticamente atualizável se atender a todas as seguintes condições:

  • A visão deve ter exatamente uma entrada em sua lista FROM, que deve ser uma tabela ou outra visão atualizável.

  • A definição da visão não deve conter as cláusulas WITH, DISTINCT, GROUP BY, HAVING, LIMIT, ou OFFSET no seu nível mais alto.

  • A definição da visão não deve conter operações de conjunto (UNION, INTERSECT ou EXCEPT) no seu nível mais alto.

  • A lista de seleção da visão não deve conter nenhuma agregação, função de janela, ou função retornando conjunto.

Uma visão atualizável automaticamente pode conter uma mistura de colunas atualizáveis e não atualizáveis. Uma coluna será atualizável se for uma referência simples a uma coluna atualizável da relação base subjacente; caso contrário, a coluna será de leitura-apenas, e um erro será gerado se um comando INSERT, UPDATE ou MERGE tentar atribuir um valor a ela.

Se a visão for automaticamente atualizável, o sistema irá converter qualquer comando INSERT, UPDATE, DELETE ou MERGE na visão no comando correspondente sobre a relação base subjacente. Os comandos INSERT que possuem uma cláusula ON CONFLICT UPDATE têm suporte total.

Se uma visão atualizável automaticamente contiver uma condição WHERE, esta condição restringe quais linhas da relação base estão disponíveis para serem modificadas pelos comandos UPDATE, DELETE e MERGE na visão. Entretanto, um comando UPDATE ou MERGE pode alterar uma linha de modo que ela não satisfaça mais a condição da cláusula WHERE, ficando assim não mais visível através da visão. Da mesma forma, um comando INSERT ou MERGE pode potencialmente inserir linhas na relação base que não satisfazem a condição da cláusula WHERE, ficando assim não mais visível através da visão (ON CONFLICT UPDATE pode afetar de forma semelhante uma linha existente que não esteja visível na visão.). Pode ser usado CHECK OPTION para evitar que os comandos INSERT, UPDATE e MERGE criem linhas não visíveis através da visão.

Se uma visão atualizável automaticamente estiver marcada com a propriedade security_barrier, então todas as condições da cláusula WHERE da visão (e quaisquer condições usando operadores marcados como LEAKPROOF) serão sempre avaliadas antes de quaisquer condições que o usuário da visão tenha adicionado. Veja Regras e privilégios para obter mais detalhes. Note que, devido a isto, linhas que não são retornadas (por não passarem pelas condições WHERE do usuário) ainda assim podem acabar sendo bloqueadas. Pode ser usado o comando EXPLAIN para ver quais condições são aplicadas no nível de relação (e, portanto, não bloqueiam linhas), e quais não são.

Uma visão mais complexa que não satisfaça todas estas condições é, por padrão, de leitura-apenas: O sistema não permitirá INSERT, UPDATE, DELETE ou MERGE na visão. Pode-se obter o efeito de uma visão atualizável criando gatilhos INSTEAD OF na visão, que devem converter tentativas de inserção, etc., na visão em ações apropriadas em outras tabelas. Para obter mais informações, veja CREATE TRIGGER. Outra possibilidade é criar regras (veja CREATE RULE), mas na prática os gatilhos são mais fáceis de entender e usar corretamente. Note também que o comando MERGE não é compatível com relações que possuem regras.

Note que o usuário que realiza a inserção, atualização ou exclusão na visão deve ter o privilégio correspondente de inserção, atualização ou exclusão na visão. Além disso, por padrão, o dono da visão deve ter os privilégios relevantes nas relações base subjacentes, enquanto o usuário que realiza a atualização não precisa de nenhuma permissão nessas relações (veja Regras e privilégios). Entretanto, se a visão tiver security_invoker definido como true, o usuário que realiza a atualização, e não o dono da visão, deverá ter os privilégios relevantes nas relações base subjacentes.

Exemplos

Criação de uma visão que consiste em todos os filmes de comédia:

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

Este comando cria uma visão contendo as colunas que estão na tabela films no momento da criação da visão. Embora tenha sido usado o * para criar a visão, as colunas adicionadas à tabela posteriormente não farão parte da visão.

Criação de uma visão com LOCAL CHECK OPTION:

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

Este comando cria uma visão baseada na visão comedies, mostrando apenas os filmes com kind = 'Comedy' e classification = 'U'. Qualquer tentativa de executar um comando INSERT ou UPDATE numa linha da visão, será rejeitada se a nova linha não tiver classification = 'U', mas o tipo (kind) do filme não será verificado.

Criação de uma visão com CASCADED CHECK OPTION:

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

Este comando cria uma visão que verifica tanto o campo kind quanto o campo classification das novas linhas.

Criação de uma visão com uma mistura de colunas atualizáveis e não atualizáveis:

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 visão oferece suporte aos comandos INSERT, UPDATE e DELETE. Todas as colunas da tabela films serão atualizáveis, enquanto as colunas computadas country e avg_rating serão de leitura-apenas.

Criação de uma visão recursiva composta pelos números de 1 a 100:

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

Note que, embora o nome da visão recursiva seja qualificado pelo esquema neste CREATE, sua auto-referência interna não é qualificada pelo esquema. Isto ocorre porque o nome do CTE (Common Table Expression) criado implicitamente não pode ser qualificado pelo esquema.

Conformidade

O comando CREATE OR REPLACE VIEW é uma extensão do PostgreSQL à linguagem SQL. Assim como o conceito de visão temporária. A cláusula WITH ( ... ) também é uma extensão, assim como as visões com barreira de segurança e as visões de invocação de segurança.

Veja também

ALTER VIEW, DROP VIEW, CREATE MATERIALIZED VIEW, pg_views, pg_matviews