7.1 MySQL视图和存储过程
第一章(1)创建视图
小结
就是创建虚拟表,自动化一些重复性的查询模块,简化各种复杂操作(包括复杂的子查询和连接等)
注意视图虽然可以像一张表一样进行各种操作,但并没有真正储存数据,数据仍然储存在原始表中,视图只是储存起来的模块化的查询结果,是为了方便和简化后续进一步操作而储存起来的虚拟表。
案例
创建 sales_by_client 视图USE sql_invoicing;CREATE VIEW sales_by_client ASSELECT client_id,name,SUM(invoice_total) AS total_salesFROM clients cJOIN invoices i USING(client_id)GROUP BY client_id, name;-- 虽然实际上这里加不加上name都一样
第一章(2)更新或删除视图
小结
修改视图可以先DROP在CREATE(也可以用CREATE OR REPLACE)
视图的查询语句可以在编辑模式下查看和修改,但最好是保存为sql文件并放在源码控制妥善管理
案例
想在上一节的顾客差额视图的查询语句最后加上按差额降序排列
法1. 先删除再重建USE sql_invoicing;DROP VIEW IF EXISTS clients_balance;
-- 若不存在这个视图,直接 DROP 会报错,所以要加上 IF EXISTS 先检测有没有这个视图CREATE VIEW clients_balance AS ……ORDER BY balance DESC
第一章(3)可更新视图
小结
视图作为虚拟表/衍生表,除了可用在查询语句SELECT中,也可以用在增删改(INSERT DELETE UPDATE)语句中,但后者有一定的前提条件。
如果一个视图的原始查询语句中没有如下元素:
- DISTINCT 去重
- GROUP BY/HAVING/聚合函数 (后两个通常是伴随着 GROUP BY 分组出现的)
- UNION 纵向连接
则该视图是可更新视图(Updatable Views),可以增删改,否则只能查。
另外,增(INSERT)还要满足附加条件:视图必须包含底层原表的所有必须字段
总之,一般通过原表修改数据,但当出于安全考虑或其他原因没有某表的直接权限时,可以通过视图来修改底层数据(?),前提是视图是可更新的。
WITH CHECK OPTION 子句
小结
在视图的原始查询语句最后加上 WITH CHECK OPTION 可以防止执行那些会让视图中某些行(记录)消失的修改语句。
第二章(1)什么是存储过程
小结
存储过程三大作用:
储存和管理SQL代码 Store and organize SQL 性能优化 Faster execution 数据安全 Data
security
导航
之前学了增删改查,包括复杂查询以及如何运用视图来简化查询。
假设你要开发一个使用数据库的应用程序,你应该将SQL语句写在哪里呢?
如果将SQL语句内嵌在应用程序的代码里,将使其混乱且难以维护,所以应该将SQL代码和应用程序代码分开,将SQL代码储存在所属的数据库中,具体来说,是放在储存过程(stored procedure)和函数中。
储存过程是一个包含SQL代码模块的数据库对象,在应用程序代码中,我们调用储存过程来获取和保存数据(get and save the data)。也就是说,我们使用储存过程来储存和管理SQL代码。
使用储存程序还有另外两个好处。首先,大部分DBMS会对储存过程中的代码进行一些优化,因此有时储存过中的SQL代码执行起来会更快。
此外,就像视图一样,储存过程能加强数据安全。比如,我们可以移除对所有原始表的访问权限,让各种增删改的操作都通过储存过程来完成,然后就可以决定谁可以执行何种储存过程,用以限制用户对我们数据的操作范围,例如,防止特定的用户删除数据。
所以,储存过程很有用,本章将学习如何创建和使用它。
第二章(2)创建一个存储过程
小结
DELIMITER $$
delimiter n. 分隔符CREATE PROCEDURE 过程名() BEGIN……;……;……;END$$DELIMITER ;
BEGIN 和 END 之间包裹的是此过程(PROCEDURE)的内容(body),内容里可以有多个语句,但每个语句都要以 ; 结束,包括最后一个。
为了将过程内容内部的语句分隔符与SQL本身执行层面的语句分隔符 ; 区别开,要先用 DELIMITER(分隔符) 关键字暂时将SQL语句的默认分隔符改为其他符号,一般是改成双美元符号 $$ ,创建过程结束后再改回来。注意创建过程本身也是一个完整SQL语句,所以别忘了在END后要加一个暂时语句分隔符
注意
过程内容中所有语句都要以 ; 结尾并且因此要暂时修改SQL本身的默认分隔符,这些都是MySQL地特性,在SQL Server等就不需要这样
第二章(3)删除存储过程
这一节学习删除储存过程,这在发现储存过程里有错误需要重建时很有用。
实例
一个删除过程(get_clients)的标准模板
USE sql_invoicing;DROP PROCEDURE IF EXISTS get_clients;
-- 注意加上【IF EXISTS】,以免因为此过程不存在而报错DELIMITER $$CREATE PROCEDURE get_clients()BEGINSELECT * FROM clients;END$$DELIMITER ;CALL get_clients();
第二章(4)参数
小结
CREATE PROCEDURE 过程名
(参数1 数据类型,参数2 数据类型,……
)
BEGIN
……
END
导航
学完了如何创建和删除过程,这一节学习如何给过程添加参数
通常我们使用参数来给储存过程传值,但我们也可以用参数获取调用程序的结果值,第二个我们之后再讲
案例
创建过程 get_clients_by_state,可返回特定州的顾客USE sql_invoicing;DROP PROCEDURE IF EXISTS get_clients_by_state;DELIMITER $$CREATE PROCEDURE get_clients_by_state
(state CHAR(2) -- 参数的数据类型
)
BEGINSELECT * FROM clients cWHERE c.state = state;
END$$DELIMITER ;
参数类型一般设定为 VARCHAR,除非能确定参数的字符数
多个参数可用逗号隔开
WHERE state = state 是没有意义的,有两种方法可以区分参数和列名:一种是取不一样的参数名如 p_state 或 state_param,第二种是像上面一样给表起别名,然后用带表前缀的列名以同参数名区分开。
第二章(5)带默认值的参数
小结
给参数设置默认值,主要是运用条件语句块和替换空值函数
回顾
SQL中的条件类语句:
替换空值 IFNULL(值1,值2)
条件函数 IF(条件表达式, 返回值1, 返回值2)
条件语句块
IF 条件表达式
THEN
语句1;
语句2;
……; [ELSE](可选)
语句1;
语句2;
……; END IF;
– 别忘了【END IF】
案例1
把 get_clients_by_state 过程的默认参数设为’CA’,即默认查询加州的客户
USE sql_invoicing;DROP PROCEDURE IF EXISTS get_clients_by_state;DELIMITER $$CREATE PROCEDURE get_clients_by_state
(state CHAR(2)
)
BEGINIF state IS NULL THEN SET state = 'CA'; /* 注意别忽略SET,SQL 里单个等号 '=' 是比较操作符而非赋值操作符'=' 与 SET 配合才是赋值 */END IF;SELECT * FROM clients cWHERE c.state = state;
END$$DELIMITER ;
调用
CALL get_clients_by_state(NULL)
注意要调用过程并使用其默认值时时要传入参数 NULL ,MySQL不允许不传参数。
案例2
将 get_clients_by_state 过程设置为默认选取所有顾客
法1. 用IF条件语句块实现……
BEGINIF state IS NULL THEN SELECT * FROM clients c;ELSESELECT * FROM clients cWHERE c.state = state;END IF;
END$$
……
法2. 用IFNULL替换空值函数实现
……
BEGINSELECT * FROM clients cWHERE c.state = IFNULL(state, c.state)
END$$
……
若参数为NULL,则返回c.state,利用 c.state = c.state 永远成立来返回所有顾客,思路很巧妙。
练习
创建一个叫 get_payments 的过程,包含 client_id 和 payment_method_id 两个参数,数据类型分别为 INT(4) 和 TINYINT(1) (1个字节,能存0~255,之后会讲数据类型,好奇可以谷歌 ‘mysql int size’),默认参数设置为返回所有记录
这是一个为你的工作预热的练习
USE sql_invoicing;DROP PROCEDURE IF EXISTS get_payments;DELIMITER $$CREATE PROCEDURE get_payments
(client_id INT, -- 不用写成INT(4)payment_method_id TINYINT
)
BEGINSELECT * FROM payments pWHERE p.client_id = IFNULL(client_id, p.client_id) ANDp.payment_method = IFNULL(payment_method_id, p.payment_method);-- 再次小心这种实际工作中各表相同字段名称不同的情况
END$$DELIMITER ;
第二章(6)参数验证
小结
过程除了可以查,也可以增删改,但修改数据前最好先进行参数验证以防止不合理的修改
主要利用条件语句块和 SIGNAL ,SQLSTATE, MESSAGE_TEXT 关键字
具体来说是在过程的内容开头加上这样的语句:
IF 错误参数条件表达式 THEN
SIGNAL SQLSTATE ‘错误类型’
[SET MESSAGE_TEXT = ‘关于错误的补充信息’](可选)
案例
创建一个 make_payment 过程,含 invoice_id, payment_amount, payment_date 三个参数
CREATE DEFINER=`root`@`localhost` PROCEDURE `make_payment`(invoice_id INT,payment_amount DECIMAL(9, 2),/*9是精度, 2是小数位数。精度表示值存储的有效位数,小数位数表示小数点后可以存储的位数见:https://dev.mysql.com/doc/refman/8.0/en/fixed-point-types.html */payment_date DATE
)
BEGIN UPDATE invoices iSET i.payment_total = payment_amount,i.payment_date = payment_dateWHERE i.invoice_id = invoice_id;
END
为了防止传入像 -100 的 payment_total 这样不合理的参数,要在增加一段参数验证语句,利用的是条件语句块加SIGNAL关键字,和其他编程语言中的抛出异常等类似
具体的错误类型可通过谷歌 “sqlstate error” 查阅(推荐使用IBM的那个表),这里是 ‘22 Data Exception’ 大类中的 ‘22003 A numeric value is out of range.’ 类型
注意还添加了 MESSAGE_TEXT 以提供给用户参数错误的更具体信息。现在传入 负数的 payment_amount 就会报错 'Error Code: 1644. Invalid payment amount ’
……
BEGINIF payment_amount <= 0 THENSIGNAL SQLSTATE '22003' SET MESSAGE_TEXT = 'Invalid payment amount'; END IF;UPDATE invoices i……
END
7.1 MySQL视图和存储过程相关推荐
- MySQL视图触发器存储过程内外链接数据锁
MySQL视图触发器存储过程内外链接数据锁 视图 什么是视图 是一个虚拟表,其内容由查询定义.同真实的一样,视图包含一系列带有名称的列和行数据 视图有什么用 视图的作用就是缓存数据,可以这么理解,我把 ...
- mysql存储过程结构体_八、mysql视图、存储过程、函数以及时间调度器
1.create or replace view emp_view as select * fromt4 ;给t4表创建一个名为emp_view的视图2.drop viewemp_view 删除视图= ...
- mysql 视图触发器,MySql视图触发器存储过程详解
一个临时表被反复使用的时候,对这个临时表起一个别名,方便以后使用,就可以创建一个视图,别名就是视图的名称.视图只是一个虚拟的表,其中的数据是动态的从物理表中读出来的,所以物理表的变更回改变视图. 创建 ...
- mysql 视图调用存储过程_MySQL视图、存储过程
在线QQ客服:1922638 专业的SQL Server.MySQL数据库同步软件 什么是视图(视图) 虚拟表 内容类似于真实表,有字段和记录 该视图不以数据库中存储的数据的形式存在 行和列的数据来自 ...
- mysql视图及存储过程
目录 mysql之视图 前言 理解: 视图语句 表用例-student 视图检查选项 举例: 注意: 视图的更新 视图的作用 mysql之存储过程 存储过程定义 存储过程的特性 关于存储过程的创建及删 ...
- mysql 视图 事务 存储过程 触发器 __ 邓治安
视图 View 逻辑上的虚拟表 #创建视图 CREATE VIEW s_t(编号,姓名,性别,出生日期) AS SELECT * FROM student WITH CHECK OPTION#查询视图 ...
- mysql 视图 事务 存储过程 触发器——龙腾
视图 View 逻辑上的虚拟表 #创建视图 CREATE VIEW s_t(编号,姓名,性别,出生日期) AS SELECT * FROM student WITH CHECK OPTION#查询视图 ...
- mysql 视图调用存储过程,是否可以在视图中调用存储过程?
A similar question about sql-server has been asked here. I'm wondering if its possible in MySql. edi ...
- MySQL关于事务控制、视图、存储过程和函数
TCL语言:事务控制语言 MySQL不同的存储引擎对事务的支持不同,MySQL默认的存储引擎InnoDB支持事务. 事务的ACID属性: 原子性:事务是不可分割的工作单位,要么都发生,要么都不发生. ...
最新文章
- Tensorflow— 递归神经网络RNN
- Eclipse下FatJar插件的安装与使用
- A02_Python(基本数据类型,容器,函数,类),Numpy(数组array,数组索引,数据类型,数组中的数学,广播)
- 【Leetcode | 9】217. 存在重复元素
- LeetCode 1347. 制造字母异位词的最小步骤数
- python django restful框架_python+django+rest框架配置创建方法
- js文件代码未加载或者没有js效果
- 排序——奖学金(洛谷 P1093)
- 网管日志-06.07.13
- spotfire中文使用教程含演示数据以及二次开发思路整理
- 管家婆服务器端口修改,211端口被占用,如何设置
- 在Win 10 中插入U盘,电脑没有弹出也不显示盘符,在其他电脑就可以【亲测有效】
- 仅用 1/4 数据量还原真人语音100%细节,火山语音上新超自然对话语音合成技术...
- .net 下如何将文档文件(Word, Pdf等) 中的文本提取出来
- 【python】数字验证常用操作
- YOLOv3源码解析2-数据预处理Dataset()
- mysql难不难_mysql数据库难学吗?
- JS 位数不够自动左补0
- 网络工程基础——路由器路由器划分权限
- 本科课程:计算机网络(四)
热门文章
- 呼吁大家:坚决抵制KingRoot,不要下载安装该流氓软件!
- cocos2dx—win32平台打包成akp的方法,无需安装cygwin
- Ubuntu22.04与深度学习配置(已搭建三台服务器)
- java实现红黑树 新增节点 左旋右旋 hash取模
- JSP技术已死 ? (Java Server Page technology will die) ?
- AD PCB 错误检查
- 『MySQL』行号关联查询
- mysql c盘满了 怎么办_电脑C盘满了怎么办?这两种方法都能解决
- shiro用户登录密码错误超过次数,冻结账号30分钟
- 计算机操作题world视频,海淘缴税攻略:新手海淘课堂视频教学第九课(电脑版)!...