sql-update-view
SQL - 通过视图更新数据
Section titled “SQL - 通过视图更新数据”视图上的 SQL UPDATE 语句
Section titled “视图上的 SQL UPDATE 语句”SQL 没有专门的 ALTER VIEW 或 UPDATE VIEW 命令来更改其显示的数据。相反,您使用标准的 UPDATE 语句。当您更新一个视图时,您实际上是在修改底层基础表中的数据。这只有在该视图是“可更新的”(updatable)情况下才可能实现。
重要提示:对视图执行 UPDATE 操作会修改源表的数据。视图是数据的“窗口”,而不是数据的“副本”。
语法与更新表相同:
UPDATE view_nameSET column1 = value1, column2 = value2, ...WHERE [condition];可更新视图的概念
Section titled “可更新视图的概念”要使视图上的 UPDATE 操作成功,数据库必须能够将更改追溯到单个基础表中的特定行和列。如果视图包含以下内容,则通常不可更新:
- 多个表上的连接(Joins)
- 聚合函数(
SUM、AVG等)或GROUP BY/HAVING子句 DISTINCT- 窗口函数(Window Functions)
- 集合运算符(
UNION等) - 您试图更新的计算列(Calculated columns)
示例:更新简单视图
Section titled “示例:更新简单视图”让我们创建一个表和一个简单的、可更新的特定城市客户视图。
CREATE TABLE customers ( customer_id INT PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(255) UNIQUE, city VARCHAR(100), last_contacted_on DATE);
INSERT INTO customers VALUES(1, 'John Doe', 'john.d@example.com', 'New York', '2023-01-10'),(2, 'Jane Smith', 'jane.s@example.com', 'London', '2023-02-15'),(3, 'Peter Jones', 'peter.j@example.com', 'New York', '2023-03-20');
-- 为纽约客户创建视图CREATE VIEW v_ny_customers ASSELECT customer_id, name, email, last_contacted_onFROM customersWHERE city = 'New York';此视图是可更新的,因为它引用了单个表,并且不包含任何复杂操作。让我们通过视图更新 Peter Jones 的邮箱。
UPDATE v_ny_customersSET email = 'p.jones.new@example.com'WHERE customer_id = 3;更改会同时反映在视图和底层的 customers 表中。
-- 查询基础表以确认更改SELECT * FROM customers WHERE customer_id = 3;| 客户ID | 姓名 | 邮箱 | 城市 | 上次联系日期 |
|---|---|---|---|---|
| 3 | Peter Jones | p.jones.new@example.com | New York | 2023-03-20 |
示例:尝试更新不可更新的视图
Section titled “示例:尝试更新不可更新的视图”现在,让我们创建一个包含计算列的视图。这样的视图是不可更新的。
CREATE VIEW v_customer_summary ASSELECT customer_id, name, UPPER(city) AS city_uppercaseFROM customers;
-- 这将失败,因为 `city_uppercase` 是一个计算列。UPDATE v_customer_summarySET city_uppercase = 'LONDON'WHERE customer_id = 2;数据库将返回错误,因为它无法逆转 UPPER() 函数来更新 customers 表中的原始 city 列。
更新多行和多列
Section titled “更新多行和多列”您可以一次更新多个列并影响多行,前提是视图是可更新的。请务必小心使用 WHERE 子句。
严重警告:在 UPDATE 语句中省略 WHERE 子句将修改通过视图可见的底层表中的所有行。在执行之前务必仔细检查您的 WHERE 子句。
让我们更新纽约视图中所有客户的联系日期。
-- 更新视图中所有客户的上次联系日期UPDATE v_ny_customersSET last_contacted_on = '2024-01-01';此查询将更改 customers 表中 John Doe 和 Peter Jones 的 last_contacted_on 日期,因为他们是唯一满足视图条件的记录。