Back

    Advanced Views & Virtual Tables

    Build updatable views, security views, recursive views, and API-layer views for reusable query logic.

    ๐ŸŽฏ What You'll Learn

    • Updatable views with WITH CHECK OPTION
    • Security barrier views for safe data access
    • Recursive views for hierarchies and trees
    • INSTEAD OF triggers for multi-table views
    • API views as a stable interface layer

    โœ๏ธ Updatable Views

    Updatable views let you INSERT, UPDATE, and DELETE through them as if they were tables. PostgreSQL auto-detects when a view is simple enough to update directly.

    ๐Ÿ’ก Pro Tip โ€” WITH CHECK OPTION

    Always add WITH CHECK OPTION to filtered views. Without it, you can INSERT a row through the view that the view itself can't display โ€” a confusing "disappearing insert" bug.

    Updatable Views

    INSERT, UPDATE, DELETE through views with check option

    Try it Yourself ยป
    SQL
    -- UPDATABLE VIEWS: INSERT/UPDATE/DELETE through a view
    
    -- Simple updatable view (automatically updatable):
    CREATE VIEW v_active_employees AS
    SELECT id, name, email, department, salary
    FROM employees
    WHERE status = 'active';
    
    -- You can INSERT through the view:
    INSERT INTO v_active_employees (name, email, department, salary)
    VALUES ('New Hire', 'new@company.com', 'Engineering', 85000);
    -- Inserts into the underlying employees table
    
    -- UPDATE through the view:
    UPDATE v_active_employees SET sala
    ...

    ๐Ÿ”’ Security Views

    Security views act as a data access layer โ€” users query the view (which masks or filters data) instead of the raw table. Use security_barrier to prevent optimizer-based data leaks.

    Security Views

    Data masking, security barrier, and row-level access

    Try it Yourself ยป
    SQL
    -- SECURITY VIEWS: control data access through views
    
    -- View that masks sensitive data:
    CREATE VIEW v_customer_directory AS
    SELECT
        id,
        name,
        LEFT(email, 3) || '***@' || SPLIT_PART(email, '@', 2) AS email,
        city,
        state,
        -- Hide exact address
        city || ', ' || state AS location
    FROM customers;
    
    -- Grant view access, deny table access:
    REVOKE ALL ON customers FROM app_readonly;
    GRANT SELECT ON v_customer_directory TO app_readonly;
    
    -- Security barrier view (prevents optimi
    ...

    ๐Ÿ”„ Recursive Views

    Recursive views encapsulate recursive CTEs so that users can query hierarchies with a simple SELECT โ€” no CTE knowledge required.

    Recursive Views

    Org charts and category trees as queryable views

    Try it Yourself ยป
    SQL
    -- RECURSIVE VIEWS: encapsulate recursive CTEs
    
    CREATE RECURSIVE VIEW v_org_chart (
        employee_id, employee_name, manager_id, depth, path
    ) AS
    -- Anchor: CEO (no manager)
    SELECT id, name, manager_id, 0,
           ARRAY[name::text]
    FROM employees WHERE manager_id IS NULL
    
    UNION ALL
    
    -- Recursive: employees under each manager
    SELECT e.id, e.name, e.manager_id, oc.depth + 1,
           oc.path || e.name::text
    FROM employees e
    JOIN v_org_chart oc ON e.manager_id = oc.employee_id;
    
    -- Now anyone can query
    ...

    ๐Ÿ”€ INSTEAD OF Triggers

    Complex views joining multiple tables aren't auto-updatable. INSTEAD OF triggers intercept INSERT/UPDATE/DELETE on the view and execute custom logic against the underlying tables.

    โš ๏ธ Common Mistake

    Forgetting to handle all DML operations. If you create an INSTEAD OF INSERT trigger but not UPDATE or DELETE, those operations silently do nothing. Always implement all three or raise an error for unsupported ones.

    INSTEAD OF Triggers

    Make multi-table views updatable

    Try it Yourself ยป
    SQL
    -- INSTEAD OF triggers: make complex views updatable
    
    -- View joining multiple tables (not auto-updatable):
    CREATE VIEW v_order_details AS
    SELECT o.id AS order_id, o.order_date, o.status,
           c.name AS customer_name, c.email,
           oi.product_id, p.name AS product_name,
           oi.quantity, oi.unit_price
    FROM orders o
    JOIN customers c ON o.customer_id = c.id
    JOIN order_items oi ON o.id = oi.order_id
    JOIN products p ON oi.product_id = p.id;
    
    -- INSTEAD OF trigger handles INSERT on the view:
    CR
    ...

    ๐Ÿ”Œ API Views

    Use views as a stable API layer between your application and database. Version them for backward compatibility, and encapsulate complex logic so applications just do simple SELECTs.

    API Layer Views

    Versioned views as stable application interfaces

    Try it Yourself ยป
    SQL
    -- API VIEWS: stable interface for applications
    
    -- Version your views to avoid breaking changes:
    CREATE VIEW api.v1_products AS
    SELECT id, name, price, category, status
    FROM products
    WHERE status = 'active';
    
    CREATE VIEW api.v2_products AS
    SELECT id, name, price, category, status,
           description,              -- new in v2
           created_at,               -- new in v2
           COALESCE(discount_pct, 0) AS discount  -- renamed in v2
    FROM products
    WHERE status = 'active';
    
    -- Old applications us
    ...

    ๐Ÿ“‹ Quick Reference

    View TypeUse Case
    Simple viewAuto-updatable, single table
    Security barrierPrevent optimizer data leaks
    Recursive viewHierarchy queries for non-experts
    INSTEAD OFCustom DML on complex views
    API viewStable versioned interface

    ๐ŸŽ‰ Lesson Complete!

    You've mastered advanced view patterns for security, reuse, and API design. Next, explore analytical SQL for business intelligence!

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy Policy โ€ข Terms of Service