Updated on 2024-06-03 GMT+08:00

CREATE VIEW

Description

Creates a view. A view is a virtual table. Only view definition is stored in the database and view data is not. The data is stored in a base table. If data in the base table changes, the data in the view changes accordingly. In this sense, a view is like a window through which users can know their interested data and data changes in the database.

  • You can define frequently used data as views to encapsulate complex query SQL statements, which simplifies operations.
  • You can query only data defined in a view, which is secure. Columns in a base table are hidden to protect the data structure of the database.
  • User permission management is simplified. Only the permission to use views is granted to users.

Precautions

A user granted with the CREATE ANY TABLE permission can create views in the public and user schemas.

Syntax

CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] VIEW view_name [ ( column_name [, ...] ) ]
    [ WITH ( {view_option_name [= view_option_value]} [, ... ] ) ]
    AS query
    [ WITH [ CASCADED | LOCAL ] CHECK OPTION  | WITH READ ONLY ];

You can use WITH(security_barrier) to create a relatively secure view. This prevents attackers from printing hidden base table data by using the RAISE statement of low-cost functions.

After a view is created, you are not allowed to use REPLACE to modify column names in the view or delete the columns.

Parameters

  • OR REPLACE

    (Optional) Redefines the view if it already exists.

  • TEMP | TEMPORARY

    (Optional) Creates a temporary view. The view is automatically deleted when the current session ends. If any table referenced by a view is a temporary table, the view is created as a temporary view (regardless of whether TEMP|TEMPORARY is specified in the SQL statement).

  • view_name

    Specifies the name (optionally schema-qualified) of the view to be created.

    Value range: a string. It must comply with the naming convention.

  • column_name

    Specifies an optional list of names to be used for columns of the view. If not given, the column names are deduced from the query.

    Value range: a string. It must comply with the naming convention.

  • view_option_name [= view_option_value]

    Specifies an optional parameter for a view.

    Currently, view_option_name supports only security_barrier and check_option.

    security_barrier: This parameter is used when the view attempts to provide row-level security. Value range: Boolean (true or false).

    check_option: controls the behavior of updating a view. Value range: CASCADED and LOCAL.

  • query

    Specifies a SELECT or VALUES statement that will provide the columns and rows of the view.

    If query contains a clause specifying the partition of a partitioned table, the OID of the specified partition is fixed to the system catalog when the view is created. If a DDL operation that will change the OID of the specified partition is used, for example, DROP, SPLIT, or MERGE, the view is unavailable. In this case, you need to create a view.

  • WITH [ CASCADED | LOCAL ] CHECK OPTION

    Controls the behavior of updatable views. INSERT and UPDATE on the view will be checked to ensure that new rows meet the view-defining condition, that is, the new rows are visible through the view. If the check fails, the modification is rejected. If this option is not added, INSERT and UPDATE on the view are allowed to create rows that are not visible through the view. WITH CHECK OPTION can be set to CASCADED or LOCAL:

    CASCADED: New rows are checked against the conditions of the view and all underlying views. If CHECK OPTION is specified, and neither LOCAL nor CASCADED is specified, then CASCADED is used by default.

    LOCAL: New rows are only checked against the conditions defined directly on the view itself. Any conditions defined on underlying views are not checked (unless they also specify CHECK OPTION).

  • WITH READ ONLY

    A read-only view is defined. You cannot insert, update, or delete data in the view.

    • The concepts involved in the constraints on updating, inserting, and deleting views are described as follows:
      • Join view: view created with multiple tables using JOIN.
      • Key-preserved table: Insertion, update, and deletion of multi-table join views are restricted by key-preserved tables. In a multi-table view, if each row in the source table corresponds to each row in the view, and a row in the source table does not correspond to multiple rows in the view after the JOIN, the source table is a key-preserved table.
      • Relationship between the top layer and the bottom layer: A view may be nested at multiple layers. For example, a view consists of one or more views or subqueries. The view that is directly operated by the DML is called the top layer. The tables and views that form the view and the tables and views in the WITH clause are called the corresponding bottom layer.
      • Columns that can be updated: Columns that are not system columns or whole-row references and directly reference user columns in the base table can be updated. You can query the is_updatable column in information_schema.columns to check whether a column in a view or table can be updated.
      • Updatable view: view that can be inserted, updated, or deleted. Updatable views do not contain DISTINCT, GROUP BY, HAVING, LIMIT and OFFSET clauses, set operations (UNION, INTERSECT, and EXCEPT), aggregate functions, window functions, and return set functions (array_agg, json_agg, and generate_series). WITH CHECK OPTION can be defined only on updatable views. To check whether a view can be updated, query the is_updatable and is_insertable_into columns in information_schema.views or the information_schema.tables.is_insertable_into column. In information_schema.views, is_updatable specifies whether a view can be updated or deleted, is_insertable_into specifies whether data can be inserted into a view, and information_schema.tables.is_insertable_into specifies whether data can be inserted into a relationship.
    • If an updatable view has an INSTEAD OF trigger or INSTEAD rule, using CHECK OPTION does not check the conditions on that view.
    • If an underlying view of an updatable view has an INSTEAD OF trigger and the updatable view defines the CHECK OPTION option of the CASCADED type, in non-A-compatible mode, the conditions of the underlying view with the INSTEAD OF trigger are recursively checked, and the conditions of the underlying view with the trigger are not checked. In A-compatible mode, the CHECK OPTION option of all views is invalid and no check is performed.
    • If CASCADED CHECK OPTION is defined in the upper-layer view and LOCAL CHECK OPTION is defined in the lower-layer view, LOCAL CHECK OPTION in the lower-layer view is overwritten by CASCADED CHECK OPTION in the upper-layer view.
    • If an updatable view or any of its underlying relationships has an INSTEAD rule that causes INSERT or UPDATE rewriting, using CHECK OPTION will not check the conditions on all views.
    • If CHECK OPTION is specified, insert and update operations cannot be performed on join columns in multi-table join views or multi-table join subqueries.
    • If CHECK OPTION is specified, duplicate base tables exist in a multi-table join view or multi-table join subquery, and the duplicate base tables are not all key-preserved tables, the view or subquery cannot be deleted.

Examples

  • Common view:
    -- Create the test_tb1 table and insert 100 data records into the table.
    gaussdb=# CREATE TABLE test_tb1(col1 int, col2 int);
    gaussdb=# INSERT INTO test_tb1 VALUES (generate_series(1,100),generate_series(1,100));
    -- Create a view whose value of col1 is less than 3.
    gaussdb=# CREATE VIEW test_v1 AS SELECT * FROM test_tb1 WHERE col1 < 3;
    -- Query a view.
    gaussdb=# SELECT * FROM test_v1;
     col1 | col2 
    ------+------
        1 |    1
        2 |    2
    (2 rows)
    
    -- Delete the table and the view.
    gaussdb=# DROP VIEW test_v1;
    gaussdb=# DROP TABLE test_tb1;
  • Temporary view:
    -- Create a table and a temporary view.
    gaussdb=# CREATE TABLE test_tb2(c1 int, c2 int);
    gaussdb=# CREATE TEMP VIEW test_v2 AS SELECT * FROM test_tb2;
    -- Query the table and view information. (The temporary table belongs to a schema starting with pg_temp instead of public.)
    gaussdb=# \d
                                                 List of relations
              Schema          |   Name   | Type  | Owner |                       Storage                        
    --------------------------+----------+-------+-------+------------------------------------------------------
     pg_temp_dn_6001_1_1_9473 | test_v2  | view  | omm   | 
     public                   | test_tb2 | table | omm   | {orientation=row,compression=no,storage_type=USTORE}
    (2 rows)
    
    -- Exit the current session and log in again. Check whether the temporary view is deleted.
    gaussdb=# \d
                                        List of relations
     Schema |   Name   | Type  | Owner |                       Storage                        
    --------+----------+-------+-------+------------------------------------------------------
     public | test_tb2 | table | omm   | {orientation=row,compression=no,storage_type=USTORE}
    (1 row)
    
    -- Delete the table.
    gaussdb=# DROP TABLE test_tb2;
  • Insert, update, and delete views.
    -- Create a single table view.
    gaussdb=# CREATE TABLE t_view_iud1 (x int, y int);
    CREATE TABLE
    gaussdb=# INSERT INTO t_view_iud1 VALUES (11, 11);
    INSERT 0 1
    gaussdb=# CREATE VIEW vt AS SELECT * FROM t_view_iud1;
    CREATE VIEW
    gaussdb=# CREATE VIEW vt_wco AS SELECT * FROM t_view_iud1 WHERE x > 5 WITH CHECK OPTION;
    CREATE VIEW
    
    -- View the information_schema.columns view and check whether columns in the view can be updated.
    gaussdb=# SELECT table_schema, table_name, column_name, is_updatable FROM information_schema.columns WHERE table_schema = current_schema AND table_name = 'vt';
     table_schema | table_name | column_name | is_updatable
    --------------+------------+-------------+--------------
     public       | vt         | y           | YES
     public       | vt         | x           | YES
    (2 rows)
    
    -- Insert and update data in a view. If WITH CHECK OPTION is specified when a view is created, data is checked before the view is updated.
    gaussdb=# INSERT INTO vt VALUES (1, 1);
    INSERT 0 1
    gaussdb=# INSERT INTO vt_wco VALUES (1, 1);
    ERROR:  new row violates WITH CHECK OPTION for view "vt_wco"
    DETAIL:  Failing row contains (1, 1).
    gaussdb=# UPDATE vt SET y = 121 WHERE y = 1;
    UPDATE 1
    gaussdb=# UPDATE vt_wco SET y = 6 WHERE y = 11;
    UPDATE 1
    gaussdb=# DELETE FROM vt WHERE y =11;
    DELETE 0
    
    -- Create a multi-layer nested view and specify WITH CHECK OPTION in the bottom-layer relationship. Check the corresponding conditions when DML operations are performed on the top-layer view.
    gaussdb=# CREATE VIEW vvtt AS SELECT * FROM vt_wco;
    CREATE VIEW
    gaussdb=# INSERT INTO vvtt VALUES (1, 1), (2, 2);
    ERROR:  new row violates WITH CHECK OPTION for view "vt_wco"
    DETAIL:  Failing row contains (1, 1).
    
    -- View information_schema.tables and information_schema.views and check whether they can be inserted and updated.
    gaussdb=# SELECT table_schema, table_name, is_insertable_into FROM information_schema.tables
    gaussdb-# WHERE table_schema = current_schema AND table_name = 'vvtt';
     table_schema | table_name | is_insertable_into
    --------------+------------+--------------------
     public       | vvtt       | YES
    (1 row)
    
    gaussdb=# SELECT table_name, is_updatable, check_option FROM information_schema.views
    gaussdb-# WHERE table_schema = current_schema AND table_name = 'vvtt';
     table_name | is_updatable | check_option
    ------------+--------------+--------------
     vvtt       | YES          | NONE
    (1 row)
    
    gaussdb=# SELECT table_name, is_updatable, check_option FROM information_schema.views WHERE table_schema = current_schema AND table_name = 'vt_wco';
     table_name | is_updatable | check_option
    ------------+--------------+--------------
     vt_wco     | YES          | CASCADED
    (1 row)
    
    -- Delete the view and table.
    gaussdb=# DROP VIEW vvtt, vt, vt_wco CASCADE;
    DROP VIEW
    gaussdb=# DROP TABLE t_view_iud1;
    DROP TABLE

Helpful Links

ALTER VIEW and DROP VIEW