Mosh|SQL教程第六弹

一、视图

1、创建视图CREATE VIEW viewname AS

这样就可以在左侧导航栏看到新增的view了,如果没有的话刷新一下就好了

可以把视图当表格使用

或者

注意:视图不存储数据,数据存储在表中

练习:创建一个视图,叫做客户结余,存储每位客户的结余,包含client_id、name、balance列。结余的计算方法是用发票表中的发票总额减去支付总额

2、修改或删除视图

删除视图:DROP VIEW view_name

一般来说我们不直接删除视图,可以使用REPLACE进行修改

复制代码
CREATE OR REPLACE VIEW clients_balance AS
SELECT c.client_id,c.name,SUM(invoice_total - payment_total) balance
FROM clients c
LEFT JOIN invoices i USING (client_id)
GROUP BY client_id ,name;

3、可更新视图

创建一个不包含distinct、group by等方法的视图

复制代码
CREATE OR REPLACE VIEW invoices_with_balance AS
SELECT
	invoice_id,
    number,
    client_id,
    invoice_total,
    payment_total,
    invoice_total - payment_total balance,
    invoice_date,
    due_date,
    payment_date
FROM invoices
WHERE (invoice_total - payment_total) > 0
-- 这里无法直接用balance
WITH CHECK OPTION;
-- 防止update或delete操作将行从视图删除

更新视图,比如删除invoice_id = 1

复制代码
DELETE FROM invoices_with_balance
WHERE invoice_id = 1;

或者 更新invoice_id = 2 的日期延后两天

复制代码
UPDATE invoices_with_balance
SET due_date = DATE_ADD(due_date,INTERVAL 2 DAY)
WHERE invoice_id = 2;

二、存储过程

1、创建一个存储,BEGIN ... END 中间是存储的内容

复制代码
-- DELIMITER改变默认分隔符 可以自定义任何没有在SQL用到的字符序列
-- 一般用的是 $$ 
DELIMITER $$
CREATE PROCEDURE get_clients()
BEGIN
	SELECT * FROM clients; -- 使用多条语句用分号分割 
END$$
DELIMITER ; -- 将分隔符改回 ;

通过运行代码,可以看到成功生成了一个存储,通过闪电符号可以进行查看数据。

复制代码
-- 也可以使用CALL来查看
CALL get_clients();

练习:获取有结余的发票(即结余大于0) ,这里可以使用之前创建的视图

复制代码
DELIMITER $$
CREATE PROCEDURE get_invoices_with_balance()
BEGIN
	SELECT * 
    FROM invoices_with_balance
    WHERE balance > 0;
END$$
DELIMITER ; 

也可以选择直接通过可视化界面创建,在Stored Procedures上右键选择Create Stored Procedure

在这个窗口就不需要担心分隔符的问题了

2、删除存储过程

DROP PROCEDURE name

复制代码
DROP PROCEDURE get_invoices_with_balance;

或者保险起见:

复制代码
DROP PROCEDURE IF EXISTS get_invoices_with_balance;

3、配合参数使用

复制代码
-- 获取州名和该州的客户
DELIMITER $$
CREATE PROCEDURE get_clients_by_state(state CHAR(2))
BEGIN
	SELECT * 
    FROM clients c
    WHERE c.state = state;
END$$
DELIMITER ; 

可以看到左侧菜单栏出现了新的存储,点击运行会弹出框让我们输入参数

或者通过sql语句查询(不填值会报错,sql中所有参数必须填值)

复制代码
CALL sql_invoicing.get_clients_by_state('CA');

得到结果如下:

练习:写一个存储,返回给定客户的发票get_invoices_by_client

复制代码
DROP PROCEDURE IF EXISTS get_invoices_by_client;

DELIMITER $$
CREATE PROCEDURE get_invoices_by_client(client_id INT) -- 根据clients中client_id的数据类型
BEGIN
	SELECT * 
    FROM invoices i
    WHERE i.client_id = client_id;
END$$
DELIMITER ; 

带默认值的参数

复制代码
DROP PROCEDURE IF EXISTS get_clients_by_state;

DELIMITER $$
CREATE PROCEDURE get_clients_by_state(state CHAR(2))
BEGIN
	IF state IS NULL THEN
		SET state = 'CA';
	END IF;
	SELECT * 
    FROM clients c
    WHERE c.state = state;
END$$
DELIMITER ; 

或者

复制代码
DROP PROCEDURE IF EXISTS get_clients_by_state;

DELIMITER $$
CREATE PROCEDURE get_clients_by_state(state CHAR(2))
BEGIN
	IF state IS NULL THEN
		SET state = 'CA';
	ELSE
		SELECT * 
		FROM clients c
		WHERE c.state = state;
	END IF;
END$$
DELIMITER ; 

或者

复制代码
DROP PROCEDURE IF EXISTS get_clients_by_state;

-- 获取州名和该州的客户
DELIMITER $$
CREATE PROCEDURE get_clients_by_state(state CHAR(2))
BEGIN
		SELECT * 
		FROM clients c
		WHERE c.state = IFNULL('CA',state);
END$$
DELIMITER ; 

查询 ,返回 state = 'CA'的客户

复制代码
CALL get_clients_by_state(NULL);

练习:写一个存储过程get_payments,带两个参数:client_id(int),payment_method_id(tinyint)

复制代码
DELIMITER $$
CREATE PROCEDURE get_payments(client_id INT,payment_method_id TINYINT) 
BEGIN
	SELECT * 
    FROM payments p
    WHERE p.client_id = IFNULL(client_id,p.client_id) AND
		  p.payment_method = IFNULL(payment_method_id,p.payment_method);
END$$
DELIMITER ; 

测试:

复制代码
call sql_invoicing.get_payments(1, NULL);

得到结果:

相关推荐
asdfg12589635 分钟前
一文通俗理解JDBC中的核心概念+案例
java·数据库·oracle·jdbc
点灯小铭12 分钟前
基于单片机与DAC0832的双路波形信号发生系统设计
数据库·单片机·mongodb·毕业设计·课程设计·期末大作业
小陈phd17 分钟前
Text2SQL智能体学习笔记(二)——NL2SQL落地的隐形基石:元数据库
数据库·笔记·学习
霸道流氓气质18 分钟前
阿里云 OSS 从零到实战:概念、配置与 Spring Boot 集成指南
数据库·spring boot·阿里云
茉莉玫瑰花茶19 分钟前
综合案例 - AI 智能租房助手 [ 4 ]
数据库·python·ai·langgraph
可乐ea20 分钟前
【Spring Boot + MyBatis|第4篇】MyBatis 动态 SQL:if、where、foreach 使用详解
java·spring boot·后端·sql·mybatis
ULIi096kr21 分钟前
MySQL查看表创建时间、修改时间、最后更新时间(精准排查僵尸表)
数据库·mysql
折哥的程序人生 · 物流技术专研34 分钟前
Tomcat 严重警告:JDBC 驱动未注销 + 工作线程泄漏 —— 原因、影响与彻底修复(生产级终极指南)
java·运维·数据库·mysql·oracle·tomcat
初圣魔门首席弟子39 分钟前
Qt C++ 项目实战:修改共享头文件后的高效增量编译与快速发布流程
数据库
wb0430720140 分钟前
仓库搬家不停业——从阿明的“在线换仓库“,看数据库迁移与 Schema 演进的实战方法论
数据库·adb·架构