MySQL视图

1. 视图(View)

视图是虚拟存在的表 ,只保存 SQL 逻辑,不保存查询结果。数据在使用时动态生成。

1.1 基本操作

复制代码
-- 创建
CREATE [OR REPLACE] VIEW 视图名[(列列表)] AS SELECT语句 [WITH [CASCADED|LOCAL] CHECK OPTION];

-- 查询
SHOW CREATE VIEW 视图名;
SELECT * FROM 视图名;

-- 修改
ALTER VIEW 视图名[(列列表)] AS SELECT语句;

-- 删除
DROP VIEW [IF EXISTS] 视图名;

1.2 检查选项(CHECK OPTION)

对视图的 INSERT/UPDATE 操作进行约束检查。

|------------------|-------------------------------|
| 选项 | 说明 |
| CASCADED(默认) | 级联检查当前视图和所有依赖视图的条件 |
| LOCAL | 仅检查自身有 CHECK OPTION 的依赖视图 |

复制代码
-- 示例:保护视图数据边界
CREATE VIEW v1 AS SELECT id, name FROM student WHERE id <= 20;
-- INSERT INTO v1 VALUES(25, 'Tom');  -- 允许插入(无 CHECK OPTION)

CREATE VIEW v2 AS SELECT id, name FROM v1 WHERE id >= 10 WITH CASCADED CHECK OPTION;
-- INSERT INTO v2 VALUES(25, 'Tom');  -- 拒绝(违反 id <= 20)

1.3 视图不可更新的情况

视图中包含以下任一内容,则不可更新(无法 INSERT/UPDATE/DELETE):

  • 聚合函数(SUM、COUNT、AVG、MIN、MAX)
  • DISTINCT
  • GROUP BY / HAVING
  • UNION / UNION ALL
  • 子查询位于 SELECT 列表中
  • 常量视图

1.4 视图的作用

|-----------|-----------------------|
| 作用 | 说明 |
| 简化操作 | 将复杂查询封装为视图,多次复用 |
| 安全性 | 限制用户只能访问特定行/列(屏蔽敏感字段) |
| 数据独立性 | 屏蔽底层表结构变化,上层应用无感知 |


2. 存储过程(Stored Procedure)

存储过程是预编译 并存储在数据库中的 SQL 集合,支持封装、复用、参数传递。

2.1 基本语法

复制代码
-- 创建(命令行需先 DELIMITER $$ 改变分隔符)
CREATE PROCEDURE 名称([IN|OUT|INOUT 参数名 类型])
BEGIN
    -- SQL 语句;
END;

-- 调用
CALL 名称([参数]);

-- 查看
SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA='库名';
SHOW CREATE PROCEDURE 名称;

-- 删除
DROP PROCEDURE [IF EXISTS] 名称;

2.2 参数模式

|------------|--------|
| 模式 | 说明 |
| IN(默认) | 传入参数 |
| OUT | 返回值 |
| INOUT | 既传入又返回 |

2.3 变量

复制代码
-- 系统变量
SELECT @@session.autocommit;
SET SESSION autocommit = 0;

-- 用户定义变量
SET @name = 'Tom';
SELECT @name;

-- 局部变量(存储过程中)
DECLARE 变量名 类型 [DEFAULT 默认值];

2.4 流程控制

复制代码
-- IF
IF 条件 THEN
    ...
ELSEIF 条件 THEN
    ...
ELSE
    ...
END IF;

-- CASE
CASE 变量
    WHEN 值1 THEN ...
    WHEN 值2 THEN ...
    ELSE ...
END CASE;

-- WHILE
WHILE 条件 DO
    ...
END WHILE;

-- REPEAT
REPEAT
    ...
UNTIL 条件 END REPEAT;

-- LOOP(需配合 LEAVE 退出)
label: LOOP
    ...
    IF 条件 THEN LEAVE label; END IF;
END LOOP label;

2.5 游标(Cursor)

用于逐行处理查询结果集。

复制代码
-- 声明
DECLARE 游标名 CURSOR FOR 查询语句;
-- 打开
OPEN 游标名;
-- 获取一行
FETCH 游标名 INTO 变量1, 变量2, ...;
-- 关闭
CLOSE 游标名;

2.6 条件处理程序(Handler)

复制代码
DECLARE {CONTINUE|EXIT} HANDLER FOR
    {SQLSTATE 'code' | SQLWARNING | NOT FOUND | SQLEXCEPTION}
    处理语句;

|----------|-------|
| 处理方式 | 说明 |
| CONTINUE | 继续执行 |
| EXIT | 退出当前块 |

2.7 完整示例

复制代码
-- 根据年龄参数,查询用户姓名和专业,插入新表
CREATE PROCEDURE p1(IN uage INT)
BEGIN
    DECLARE uname VARCHAR(100);
    DECLARE upro VARCHAR(100);
    -- 声明游标
    DECLARE u_cursor CURSOR FOR SELECT name, profession FROM tb_user WHERE age <= uage;
    -- 声明异常处理:游标读取完毕时关闭
    DECLARE EXIT HANDLER FOR SQLSTATE '02000' CLOSE u_cursor;
    -- 建表
    DROP TABLE IF EXISTS tb_user_pro;
    CREATE TABLE IF NOT EXISTS tb_user_pro(
        id INT PRIMARY KEY AUTO_INCREMENT,
        name VARCHAR(100),
        profession VARCHAR(100)
    );
    -- 打开游标循环
    OPEN u_cursor;
    WHILE TRUE DO
        FETCH u_cursor INTO uname, upro;
        INSERT INTO tb_user_pro VALUES(NULL, uname, upro);
    END WHILE;
    CLOSE u_cursor;
END;

CALL p1(30);

注意:先声明变量,再声明游标。游标声明必须在 Handler 声明之前。


3. 存储函数(Stored Function)

与存储过程类似,但必须有返回值。

复制代码
CREATE FUNCTION 函数名([参数 类型, ...])
RETURNS 返回类型 [DETERMINISTIC]
BEGIN
    -- SQL 逻辑
    RETURN 值;
END;

-- 调用
SELECT 函数名(参数);

4. 触发器(Trigger)

在 INSERT / UPDATE / DELETE 前后自动触发执行。用于数据校验、日志记录、审计等场景。

目前 MySQL 只支持行级触发(FOR EACH ROW)。

4.1 NEW 和 OLD

|--------|-------|-------|
| 触发器类型 | NEW | OLD |
| INSERT | 新数据 | 无 |
| UPDATE | 修改后数据 | 修改前数据 |
| DELETE | 无 | 被删除数据 |

4.2 语法

复制代码
CREATE TRIGGER 触发器名
{BEFORE | AFTER} {INSERT | UPDATE | DELETE}
ON 表名 FOR EACH ROW
BEGIN
    -- SQL 语句(可通过 NEW.字段 / OLD.字段 引用数据)
END;

SHOW TRIGGERS;                          -- 查看
DROP TRIGGER [schema.]触发器名;          -- 删除

4.3 示例:审计日志

复制代码
CREATE TRIGGER user_log AFTER INSERT ON user FOR EACH ROW
BEGIN
    INSERT INTO audit_log(user_id, action, create_time)
    VALUES(NEW.id, 'INSERT', NOW());
END;

|------|-----------|------------|--------|-------------|
| 特性 | 视图 | 存储过程 | 函数 | 触发器 |
| 主要用途 | 封装查询,简化访问 | 封装业务逻辑 | 计算并返回值 | 自动响应 DML 事件 |
| 返回值 | 虚拟表 | 可选(OUT 参数) | 必须有 | 无 |
| 调用方式 | SELECT | CALL | SELECT | 自动触发 |

相关推荐
这个DBA有点耶2 小时前
测试全绿,上线三周数据没入账——那个95%的兼容度报告,漏掉的是边界
数据库·mysql·架构
1024奇点2 小时前
【仓颉语言入门 · 第二篇 第 15 课】
开发语言·数据库·ide·开源
疯狂学习GIS2 小时前
将谷歌地球引擎账号升级为Contributor与Partner层级的方法
java·数据库·人工智能
gf13211112 小时前
python_高德地图驾车时长查询
数据库·python·mysql
时间售卖铺3 小时前
MySQL 日志管理
运维·数据库·mysql·云原生
秋风点枝3 小时前
数据库 01 · 体系结构与存储引擎
数据库·mysql
CodeGL3 小时前
15、Python 访问数据库
数据库·python
小此方3 小时前
Re:Mysql数据库基础篇(五):拒绝脏数据!一文吃透MySQL表的约束(主键、唯一键、外键与实战案例)
数据库·mysql
想做小南娘,发现自己是女生喵3 小时前
LAN Device Monitor 第二周学习文档
java·服务器·数据库