SQL Views: Master Creating, Updatable vs Read-Only Views, Management with Examples & Best Practices
Table of Contents
1. What are views in SQL?


A view is a virtual table defined by a stored SQL query, presenting data from one or more tables without storing the data physically. Views simplify complex queries, enhance security by restricting access, and provide a consistent interface for data access.
Types:
- Simple Views: Based on a single table, often updatable.
- Complex Views: Involve joins, aggregations, or subqueries, typically read-only.
Syntax:
CREATE VIEW view_name AS
SELECT column1, column2 FROM table_name WHERE condition;Management: Views can be altered, dropped, or granted permissions.
Support: MySQL, PostgreSQL, SQL Server, Oracle, SQLite.
2. How do you create and manage views?
- Create View: Define the view with a SELECT query.
- Alter View: Modify the view's query definition.
- Drop View: Remove the view from the database.
- Grant Permissions: Control access to the view.
Use Case: Simplifying reports or hiding sensitive data (e.g., employee salaries).
3. Can you give an example of creating and managing views?

-- Create sample tables
CREATE TABLE Employees ( EmployeeID INT PRIMARY KEY, FirstName VARCHAR(50), Salary DECIMAL(10, 2), DepartmentID INT
); CREATE TABLE Departments ( DepartmentID INT PRIMARY KEY, DepartmentName VARCHAR(50)
); -- Insert sample data
INSERT INTO Departments (DepartmentID, DepartmentName)
VALUES (1, 'IT'), (2, 'HR'); INSERT INTO Employees (EmployeeID, FirstName, Salary, DepartmentID)
VALUES (1, 'John', 60000.00, 1), (2, 'Jane', 55000.00, 2), (3, 'kristal', 65000.00, 1); -- Create a simple view
CREATE VIEW EmployeeInfo AS
SELECT EmployeeID, FirstName, DepartmentID
FROM Employees
WHERE DepartmentID = 1; -- Create a complex view with join
CREATE VIEW EmployeeDetails AS
SELECT e.EmployeeID, e.FirstName, d.DepartmentName, e.Salary
FROM Employees e
JOIN Departments d ON e.DepartmentID = d.DepartmentID; -- Query views
SELECT * FROM EmployeeInfo;
SELECT * FROM EmployeeDetails; -- Alter view (modify query)
ALTER VIEW EmployeeInfo AS
SELECT EmployeeID, FirstName, DepartmentID, Salary
FROM Employees
WHERE DepartmentID = 1 AND Salary > 60000.00; -- Grant permissions (MySQL)
CREATE USER 'viewer'@'localhost' IDENTIFIED BY 'password123';
GRANT SELECT ON EmployeeInfo TO 'viewer'@'localhost'; -- SQL Server version
CREATE LOGIN viewer WITH PASSWORD = 'password123';
CREATE USER viewer FOR LOGIN viewer;
GRANT SELECT ON EmployeeInfo TO viewer; -- Drop view
DROP VIEW EmployeeInfo; -- Verify data (EmployeeDetails)
SELECT * FROM EmployeeDetails; Output (EmployeeInfo, before ALTER):
EmployeeID | FirstName | DepartmentID
-----------|-----------|-------------
1 | John | 1
3 | kristal | 1 Output (EmployeeInfo, after ALTER):
EmployeeID | FirstName | DepartmentID | Salary
-----------|-----------|-------------|----------
3 | kristal | 1 | 65000.00 Output (EmployeeDetails):
EmployeeID | FirstName | DepartmentName | Salary
-----------|-----------|---------------|----------
1 | John | IT | 60000.00
2 | Jane | HR | 55000.00
3 | kristal | IT | 65000.00 Note:
EmployeeInforestricts to IT department; later altered to includeSalaryand filter by high salaries.EmployeeDetailsjoins tables for a comprehensive view.- Permissions granted to
viewerfor read-only access. DROP VIEWremovesEmployeeInfo.
4. What are updatable and read-only views in SQL?

Updatable Views: Allow INSERT, UPDATE, or DELETE operations that directly affect the underlying table(s).
Conditions for Updatability (varies by RDBMS):
- Based on a single table.
- Includes all columns required for integrity (e.g.,
NOT NULLcolumns without defaults). - No aggregations, joins,
DISTINCT,GROUP BY, or subqueries in the view definition. - No computed columns or derived values in the
SELECT.
Use Case: Simplifying data entry while restricting column access.
Read-Only Views: Cannot be modified directly; used for reporting or security.
- Typically involve joins, aggregations, or complex logic.
- Can be enforced with
WITH CHECK OPTIONor explicit restrictions.
WITH CHECK OPTION: Ensures updates/inserts on updatable views conform to the view's WHERE clause.
Support: MySQL, PostgreSQL, SQL Server, Oracle; SQLite supports updatable views with limitations.
5. Can you give an example of updatable and read-only views?
-- Create updatable view
CREATE VIEW ITEmployees AS
SELECT EmployeeID, FirstName, Salary, DepartmentID
FROM Employees
WHERE DepartmentID = 1
WITH CHECK OPTION; -- Test updatable view
UPDATE ITEmployees
SET Salary = 62000.00
WHERE EmployeeID = 1; -- Invalid update (violates WITH CHECK OPTION)
UPDATE ITEmployees
SET DepartmentID = 2
WHERE EmployeeID = 1; -- Error: CHECK OPTION failed -- Insert into updatable view
INSERT INTO ITEmployees (EmployeeID, FirstName, Salary, DepartmentID)
VALUES (4, 'Ram', 58000.00, 1); -- Invalid insert (violates WITH CHECK OPTION)
INSERT INTO ITEmployees (EmployeeID, FirstName, Salary, DepartmentID)
VALUES (5, 'hari', 59000.00, 2); -- Error: CHECK OPTION failed -- Create read-only view (complex with join and aggregation)
CREATE VIEW DepartmentSummary AS
SELECT d.DepartmentName, COUNT(e.EmployeeID) AS EmployeeCount, AVG(e.Salary) AS AvgSalary
FROM Employees e
JOIN Departments d ON e.DepartmentID = d.DepartmentID
GROUP BY d.DepartmentName; -- Test read-only view
SELECT * FROM DepartmentSummary; -- Attempt to update read-only view (will fail)
UPDATE DepartmentSummary
SET AvgSalary = 60000.00
WHERE DepartmentName = 'IT'; -- Error: Cannot update -- Verify data
SELECT * FROM ITEmployees;
SELECT * FROM DepartmentSummary; Output (ITEmployees, after UPDATE and INSERT):
EmployeeID | FirstName | Salary | DepartmentID
-----------|-----------|----------|-------------
1 | John | 62000.00 | 1
3 | kristal | 65000.00 | 1
4 | Ram | 58000.00 | 1 Output (DepartmentSummary):
DepartmentName | EmployeeCount | AvgSalary
---------------|--------------|----------
IT | 3 | 61666.67
HR | 1 | 55000.00 Note:
ITEmployeesis updatable, allowingUPDATEandINSERTonEmployeesforDepartmentID=1.WITH CHECK OPTIONprevents updates/inserts that violate theWHEREclause.DepartmentSummaryis read-only due toJOINandGROUP BY.
6. Can you provide a comprehensive example of creating, managing, and using updatable and read-only views?

-- Create sample tables
CREATE TABLE Employees ( EmployeeID INT PRIMARY KEY, FirstName VARCHAR(50), Salary DECIMAL(10, 2) NOT NULL, DepartmentID INT
); CREATE TABLE Departments ( DepartmentID INT PRIMARY KEY, DepartmentName VARCHAR(50)
); -- Insert sample data
INSERT INTO Departments (DepartmentID, DepartmentName)
VALUES (1, 'IT'), (2, 'HR'); INSERT INTO Employees (EmployeeID, FirstName, Salary, DepartmentID)
VALUES (1, 'John', 60000.00, 1), (2, 'Jane', 55000.00, 2), (3, 'kristal', 65000.00, 1); -- Create updatable view
CREATE VIEW ITEmployeeView AS
SELECT EmployeeID, FirstName, Salary, DepartmentID
FROM Employees
WHERE DepartmentID = 1
WITH CHECK OPTION; -- Create read-only view
CREATE VIEW DepartmentStats AS
SELECT d.DepartmentName, COUNT(e.EmployeeID) AS EmployeeCount, AVG(e.Salary) AS AvgSalary, MAX(e.Salary) AS MaxSalary
FROM Employees e
JOIN Departments d ON e.DepartmentID = d.DepartmentID
GROUP BY d.DepartmentName; -- Create user for access control
CREATE USER 'hr_user'@'localhost' IDENTIFIED BY 'password123';
GRANT SELECT, UPDATE ON ITEmployeeView TO 'hr_user'@'localhost';
GRANT SELECT ON DepartmentStats TO 'hr_user'@'localhost'; -- SQL Server version
CREATE LOGIN hr_user WITH PASSWORD = 'password123';
CREATE USER hr_user FOR LOGIN hr_user;
GRANT SELECT, UPDATE ON ITEmployeeView TO hr_user;
GRANT SELECT ON DepartmentStats TO hr_user; -- Test updatable view (as hr_user)
-- Connect as hr_user and run:
UPDATE ITEmployeeView
SET Salary = 63000.00
WHERE EmployeeID = 1; INSERT INTO ITEmployeeView (EmployeeID, FirstName, Salary, DepartmentID)
VALUES (4, 'Ram', 58000.00, 1); -- Invalid update (will fail due to WITH CHECK OPTION)
UPDATE ITEmployeeView
SET DepartmentID = 2
WHERE EmployeeID = 1; -- Error: CHECK OPTION failed -- Test read-only view
SELECT * FROM DepartmentStats; -- Alter read-only view
ALTER VIEW DepartmentStats AS
SELECT d.DepartmentName, COUNT(e.EmployeeID) AS EmployeeCount, AVG(e.Salary) AS AvgSalary
FROM Employees e
JOIN Departments d ON e.DepartmentID = d.DepartmentID
GROUP BY d.DepartmentName; -- Drop view
DROP VIEW ITEmployeeView; -- Verify data
SELECT * FROM Employees;
SELECT * FROM DepartmentStats; Output (Employees, after UPDATE and INSERT):
EmployeeID | FirstName | Salary | DepartmentID
-----------|-----------|----------|-------------
1 | John | 63000.00 | 1
2 | Jane | 55000.00 | 2
3 | kristal | 65000.00 | 1
4 | Ram | 58000.00 | 1 Output (DepartmentStats, after ALTER):
DepartmentName | EmployeeCount | AvgSalary
---------------|--------------|----------
IT | 3 | 62000.00
HR | 1 | 55000.00 Description:
- Updatable View:
ITEmployeeViewallows updates/inserts for IT department;WITH CHECK OPTIONenforcesDepartmentID=1. - Read-Only View:
DepartmentStatsprovides aggregated data, modified viaALTER. - Permissions:
hr_usercan updateITEmployeeViewand readDepartmentStats. - Management: View is dropped with
DROP VIEW. - Integrates prior concepts (
SELECT,JOIN,GROUP BY, permissions).
7. What are common mistakes when working with views?
Creating/Managing Views:
- Creating complex views with poor performance (e.g., excessive joins or subqueries).
- Not validating view queries, causing errors when accessed.
- Forgetting to update views after schema changes, leading to invalid views.
Updatable Views:
- Assuming all views are updatable, ignoring restrictions (e.g., joins, aggregations).
- Omitting
WITH CHECK OPTION, allowing invalid updates/inserts. - Not including mandatory columns (e.g.,
NOT NULLwithout defaults).
General:
- Granting excessive permissions on views, exposing sensitive data.
- Not indexing underlying tables, slowing view performance.
- Using views for logic better suited to stored procedures.
8. What are best practices for working with views?

Creating/Managing Views:
- Use descriptive names (e.g.,
ITEmployeeView) and comment view purpose. - Test view queries independently before creating the view.
- Regularly review and update views after schema changes.
Updatable Views:
- Use
WITH CHECK OPTIONto enforce view conditions on updates/inserts. - Ensure all mandatory columns are included in updatable views.
- Test updates/inserts with edge cases (e.g.,
NULLvalues, constraint violations).
Performance:
- Index underlying table columns used in view
WHERE,JOIN, orGROUP BYclauses. - Use
EXPLAINto analyze view query performance. - Avoid excessive joins or aggregations in views for frequent access.
Security:
- Grant minimal permissions on views (e.g.,
SELECTonly for read-only users). - Use views to hide sensitive columns or rows instead of granting table access.
- Combine views with roles for scalable access control.
General:
- Document view purpose and restrictions (e.g., updatable or read-only).
- Monitor view usage with RDBMS tools (e.g., PostgreSQL
pg_stat_user_tables). - Drop unused views to reduce database clutter.
- Use transactions for updates via views to ensure consistency.