8、SQL语言(6)

时间:2021-01-03 00:46:20
视图VIEW

MySQL视图是一个虚拟表格,是通过对一个或多个现有的表进行SELECT语句定义的。视图不像表那样存储数据,而是在查询时动态生成;虚拟表,保存有实表的查询结果,相当于别名

MySQL视图可以用来:

1.简化数据访问:可以将多个相关联的表组合起来在一个地方生成一个虚拟表,从而简化数据访问。

2.提供更好的数据安全性:视图使得只有授权用户可以访问敏感数据,从而增加数据的安全性。

3.提高查询性能: MySQL视图中已经定义好了SQL语句,这样可以提高查询性能。

创建方法:

CREATE VIEW view_name [(column_list)] AS select_statement [WITH [CASCADED | LOCAL] CHECK OPTION]

例如:假设我们有一个Orders表和一个Customers表,我们可以通过以下代码创建一个视图:
CREATE VIEW customer_orders AS
SELECT customers.customer_name, orders.order_date, orders.total
FROM customers
INNER JOIN orders ON customers.customer_id = orders.customer_id;
这个视图将返回每个客户的订单日期和总数以及他们的名称 。
可以像访问表一样访问视图,例如:
SELECT * FROM customer_orders;

8、SQL语言(6)

8、SQL语言(6)

查看视图定义:

SHOW CREATE VIEW view_name #只能看视图定义
SHOW CREATE TABLE view_name # 可以查看表和视图

8、SQL语言(6)

8、SQL语言(6)

8、SQL语言(6)

8、SQL语言(6)

8、SQL语言(6)

删除视图:

DROP VIEW [IF EXISTS]
view_name [, view_name] ...
[RESTRICT | CASCADE]

具体而言,当视图被其他对象(如存储过程、触发器等)引用时,DROP VIEW 命令可能会受到以下约束:
如果使用了 RESTRICT 参数,则当视图被其他对象引用时,DROP VIEW 命令将被拒绝,并显示错误消息。这是默认的行为。
如果使用了 CASCADE 参数,则当视图被其他对象引用时,DROP VIEW 命令将删除这些对象,并删除视图本身,在使用 CASCADE 参数之前,需要仔细考虑和测试您的代码,以确保删除视图时不会影响其他对象。

注意:视图中的数据事实上存储于“基表”中,因此,其修改操作也会针对基表实现;其修改操作受基表限制

8、SQL语言(6)


函数FUNCTION

函数是一种可重用的程序模块,它接受零个或多个参数,并在执行期间执行一系列操作,最终返回一个值。

函数可以用来简化复杂的查询,提高查询的可重用性,并使代码更易于维护。与存储过程类似,函数也可以在 MySQL 中创建、修改和删除。

MySQL 支持多种类型的函数,包括标量函数、聚合函数和窗口函数等。

标量函数:接受一个或多个参数,并返回单个值。常见的标量函数包括字符串函数(如 CONCAT、SUBSTR 等)、数学函数(如 ABS、ROUND 等)、日期函数(如 NOW、DATE_ADD 等)等。

聚合函数:接受多个值作为输入,并计算汇总结果。常见的聚合函数包括 SUM、AVG、COUNT、MAX、MIN 等。

窗口函数:将某个函数应用于一组行,然后将结果作为单个值返回。窗口函数可以用来计算滑动平均值、累计总和、排名等。MySQL 8.0 之后支持窗口函数。

在 MySQL 中,可以使用 CREATE FUNCTION 命令创建函数,使用 ALTER FUNCTION 命令修改函数,使用 DROP FUNCTION 命令删除函数。函数可以使用 SQL、PL/SQL 或 C/C++ 语言编写,其中 SQL 函数是最常见的类型。

mysql变量

MySQL中的变量

两种变量:系统内置变量和用户自定义变量

系统变量:MySQL数据库中内置的变量,可用@@var_name引用

8、SQL语言(6)

用户自定义变量分为以下两种

普通变量:在当前会话中有效,可用@var_name引用

8、SQL语言(6)

局部变量:在函数或存储过程内才有效,需要用DECLARE 声明,之后直接用 var_name引用

CREATE PROCEDURE my_procedure()
BEGIN
DECLARE var_name INT;
SET var_name = 10;
END;

创建函数

CREATE [AGGREGATE] FUNCTION function_name(parameter_name type,[parameter_name
type,...])
RETURNS {STRING|INTEGER|REAL}
runtime_body

说明:
参数可以有多个,也可以没有参数
无论有无参数,小括号()是必须的
必须有且只有一个返回值

8、SQL语言(6)

注:DELEMITER //定义//作为结束符,因mysql默认使用;作为结束符

这个警告信息表示 MySQL 检测到一个函数定义,该函数没有使用 DETERMINISTIC、NO SQL 或 READS SQL DATA 中的任何一个声明,并且二进制日志记录已启用。这可能导致二进制日志文件和主从同步出现问题。如果您确定函数不会引起任何副作用,可以通过设置 log_bin_trust_function_creators 参数来解决此问题。但是需要注意的是,这会降低 MySQL 的安全性,因为这将允许未经授权的用户创建具有副作用的函数。
解决此警告的方法是,在创建函数时,应该在函数头部使用 DETERMINISTIC、NO SQL 或 READS SQL DATA 中的任何一个声明,以指示该函数是确定性函数、非 SQL 函数还是只读 SQL 函数
创建函数中的一些循环判断用法
在编写函数时,有时需要使用循环来重复执行一些操作,直到满足某个条件为止。在大多数编程语言中,常见的循环结构包括for循环、while循环和do-while循环。

while 循环
CREATE FUNCTION factorial(n INT)
RETURNS INT
BEGIN
DECLARE result INT DEFAULT 1;
DECLARE i INT DEFAULT 1;
WHILE i <= n DO
SET result = result * i;
SET i = i + 1;
END WHILE;
RETURN result;
END;

for循环
CREATE FUNCTION factorial(n INT)
RETURNS INT
BEGIN
DECLARE result INT DEFAULT 1;
DECLARE i INT DEFAULT 1;
WHILE i <= n DO
SET result = result * i;
SET i = i + 1;
END WHILE;
RETURN result;
END;

do-while循环
CREATE FUNCTION factorial(n INT)
RETURNS INT
BEGIN
DECLARE result INT DEFAULT 1;
DECLARE i INT DEFAULT 1;
REPEAT
SET result = result * i;
SET i = i + 1;
UNTIL i > n END REPEAT;
RETURN result;
END;


在编写函数时,条件判断语句通常用于根据不同情况执行不同的操作。在大多数编程语言中,常见的条件判断语句包括if语句、switch语句和三元运算符。
以下是一个示例函数,其中使用if语句根据数字的正负性来计算绝对值:
if
CREATE FUNCTION absolute(n INT)
RETURNS INT
BEGIN
DECLARE result INT;
IF n < 0 THEN
SET result = -n;
ELSE
SET result = n;
END IF;
RETURN result;
END;

switch case;
CREATE FUNCTION get_color_info(color VARCHAR(20))
RETURNS VARCHAR(100)
BEGIN
DECLARE result VARCHAR(100);
CASE color
WHEN 'red' THEN
SET result = 'The color is red, it symbolizes passion and love.';
WHEN 'green' THEN
SET result = 'The color is green, it symbolizes nature and growth.';
WHEN 'blue' THEN
SET result = 'The color is blue, it symbolizes peace and tranquility.';
ELSE
SET result = 'The color is unknown.';
END CASE;
RETURN result;
END;

三目运算
CREATE FUNCTION absolute(n INT)
RETURNS INT
BEGIN
DECLARE result INT;
SET result = n < 0 ? -n : n;
RETURN result;
END;

查看函数列表

SHOW FUNCTION STATUS; 查看函数列表
SHOW CREATE FUNCTION function_name; 查看函数定义

8、SQL语言(6)

8、SQL语言(6)

调用函数

SELECT function_name(parameter_value,...)

8、SQL语言(6)

删除函数

drop function function_name

8、SQL语言(6)

存储过程PROCEDURE

存储过程(Stored Procedure)是一种预先编译的可重复使用的代码块,它由一组 SQL 语句和逻辑组成,并可以接受参数并返回值。存储过程通常用于简化复杂的操作、提高性能、保障数据安全性等。多表SQL的语句的集合,可以独立执行,存储过程保存在mysql.proc表中

存储过程与函数的区别

设计目的不同:存储过程主要用于实现一些特定的业务逻辑,例如批量操作、数据校验、数据备份等等,而函数主要用于计算、转换数据等等。
返回结果不同:存储过程可以返回多个结果集,但是不能直接作为一个表达式使用,而函数只能返回单一的值,并且可以直接作为一个表达式使用,例如作为 SELECT 语句的一部分,或者作为 WHERE 子句的条件。
参数传递方式不同:存储过程可以接受输入参数和输出参数,而函数只能接受输入参数。
事务处理方式不同:存储过程可以自己定义事务处理方式,而函数不能定义事务处理方式,通常由调用它的语句所在的事务处理。
执行方式不同:函数通常是通过 SELECT 语句调用并返回单个值,而存储过程是通过 EXECUTE 或 CALL 语句调用的,它们可以包含多个 SQL 语句并执行多个任务

创建存储过程

CREATE PROCEDURE sp_name ([ proc_parameter [,proc_parameter ...]])
routime_body
proc_parameter : [IN|OUT|INOUT] parameter_name type
说明:其中IN表示输入参数,OUT表示输出参数,INOUT表示既可以输入也可以输出;param_name
表示参数名称;type表示参数的类型
示例:
CREATE PROCEDURE get_employee_salary
@employee_id INT,
@salary INT OUTPUT
AS
BEGIN
SELECT @salary = salary
FROM employee
WHERE employee_id = @employee_id
END;
# 创建无参存储过程
delimiter //
CREATE PROCEDURE showTime()
BEGIN
SELECT now();
END//
delimiter ;
CALL showTime;

8、SQL语言(6)

带参数
delimiter //
CREATE PROCEDURE dorepeat(n INT)
BEGIN
SET @i = 0;
SET @sum = 0;
REPEAT SET @sum = @sum+@i;
SET @i = @i + 1;
UNTIL @i > n END REPEAT;
END//
delimiter ;
CALL dorepeat(100);
SELECT @sum;
#创建含参存储过程:包含IN参数和OUT参数
delimiter //
CREATE PROCEDURE deleteById(IN id SMALLINT UNSIGNED, OUT num SMALLINT UNSIGNED)
BEGIN
DELETE FROM students WHERE stuid >= id;
SELECT row_count() into num;
END//
delimiter ;
call deleteById(2,@Line);
SELECT @Line;
#说明:创建存储过程deleteById,包含一个IN参数和一个OUT参数.调用时,传入删除的ID和保存被修改的行
数值的用户变量@Line,select @Line;输出被影响行数
#row_count() 系统内置函数,用于存放前一条SQL修改过的表的记录数

流程控制(同函数)

IF:用来进行条件判断。根据是否满足条件,执行不同语句
CASE:用来进行条件判断,可实现比IF语句更复杂的条件判断
LOOP:重复执行特定的语句,实现一个简单的循环
LEAVE:用于跳出循环控制,相当于SHELL中break
ITERATE:跳出本次循环,然后直接进入下一次循环,相当于SHELL中continue
REPEAT:有条件控制的循环语句。当满足特定条件时,就会跳出循环语句
WHILE:有条件控制的循环语句

查看存储过程

SHOW PROCEDURE STATUS;
SHOW CREATE PROCEDURE sp_name

调用存储过程

call sp_name([ proc_parameter [,proc_parameter ...]])

删除存储过程

drop procedure sp_name

触发器TRIGGER

触发器(Trigger)是一种特殊类型的存储过程,它会在特定的数据库事件发生时自动执行。当满足触发器定义的条件时,触发器可以在表上执行 INSERT、UPDATE 或 DELETE 操作,从而自动更新相关数据。

在关系型数据库管理系统中,触发器通常与表关联,并在以下事件发生时触发:

INSERT:当在表中插入新行时触发。

UPDATE:当在表中更新行时触发。

DELETE:当在表中删除行时触发。

创建触发器

CREATE [DEFINER = { user | CURRENT_USER }]
TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
trigger_body

说明:
trigger_name:触发器的名称
trigger_time:{ BEFORE | AFTER },表示在事件之前或之后触发
trigger_event::{ INSERT |UPDATE | DELETE },触发的具体事件
tbl_name:该触发器作用在表名
FOR EACH ROW 或 FOR EACH STATEMENT 来指定触发器是针对每行还是每个语句执行的。
在使用 FOR EACH ROW 定义的触发器中,触发器代码将针对受影响的每一行分别执行。而在使用 FOR EACH STATEMENT 定义的触发器中,触发器代码只会执行一次,即使操作影响了多行数据。对于大多数情况,FOR EACH ROW 是更常用的选项
示例
CREATE TRIGGER order_history_trigger
AFTER INSERT
ON orders FOR EACH ROW
BEGIN
INSERT INTO order_history (order_id, order_date, customer_id, total_amount)
SELECT order_id, order_date, customer_id, total_amount
FROM inserted;
END;

8、SQL语言(6)

查看触发器

#在当前数据库对应的目录下,可以查看到新生成的相关文件:trigger_name.TRN,table_name.TRG
SHOW TRIGGERS;
#查询系统表information_schema.triggers的方式指定查询条件,查看指定的触发器信息。
USE information_schema;
SELECT * FROM triggers WHERE trigger_name='trigger_student_count_insert'

8、SQL语言(6)

8、SQL语言(6)

删除触发器

DROP TRIGGER trigger_name;
事件EVENT

MySQL事件(MySQL Event)是MySQL数据库中一种用于在指定时间执行某些操作的机制。它类似于操作系统中的计划任务(cron job)或Windows中的计划任务(Task Scheduler),可以自动执行一些SQL语句或存储过程,无需人工干预。

MySQL事件的使用可以提高数据库的效率,减少人工操作的错误率,并且可以在需要时自动执行某些操作。MySQL事件由以下几个要素组成:

事件名称(EVENT NAME):用于标识事件的名称。

时间调度(TIMESTAMP):指定事件在何时执行。

事件状态(STATUS):表示事件是否启用或禁用。

事件执行内容(EVENT BODY):指定事件要执行的SQL语句或存储过程。

使用MySQL事件可以方便地实现周期性的任务,如每日备份数据库、定时清理无用数据等。但需要注意的是,事件机制需要MySQL服务处于运行状态,因此在配置事件之前要确保MySQL服务一直处于运行状态。

事件进程启动

要使用MySQL事件,需要先启用事件调度器(Event Scheduler)。事件调度器默认是禁用的,可以通过以下步骤启用:

在MySQL客户端(如MySQL Workbench、命令行客户端等)中连接到MySQL服务器。

执行以下命令以启用事件调度器:



SET GLOBAL event_scheduler = ON;

确认事件调度器已经启用,可以通过以下命令查询:



SHOW VARIABLES LIKE 'event_scheduler';

如果输出结果为ON,则表示事件调度器已经启用。

持久开启事件调度

#持久开启事件调度
[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
event_scheduler=ON
[root@centos8 ~]#systemctl restart mariadb

8、SQL语言(6)

创建事件

CREATE
[DEFINER = { user | CURRENT_USER }]
EVENT
[IF NOT EXISTS]
event_name
ON SCHEDULE schedule
[ON COMPLETION [NOT] PRESERVE]
[ENABLE | DISABLE | DISABLE ON SLAVE]
[COMMENT 'comment']
DO event_body;

schedule:
AT timestamp [+ INTERVAL interval] ...
| EVERY interval
[STARTS timestamp [+ INTERVAL interval] ...]
[ENDS timestamp [+ INTERVAL interval] ...]
interval:
quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE |
WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |
DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}

示例:
CREATE EVENT backup_database
ON SCHEDULE EVERY 1 DAY STARTS '23:00:00'
DO
CALL backup_database_procedure();
说明:
event_name :创建的event名字,必须是唯一确定的
ON SCHEDULE:计划任务
schedule: 决定event的执行时间和频率(注意时间一定要是将来的时间,过去的时间会出错),有两种
形式 AT和EVERY
[ON COMPLETION [NOT] PRESERVE]: 可选项,默认是ON COMPLETION NOT PRESERVE 即计划任务执行完毕后自动drop该事件;ON COMPLETION PRESERVE则不会drop掉
[COMMENT 'comment'] :可选项,comment 用来描述event;相当注释,最大长度64个字节
[ENABLE | DISABLE] :设定event的状态,默认ENABLE:表示系统尝试执行这个事件, DISABLE:关闭该事情,可以用alter修改
DO event_body: 需要执行的sql语句,可以是复合语句
提示:event事件是存放在mysql.event表中

查看Event

SHOW EVENTS [{FROM | IN} schema_name]
[LIKE 'pattern' | WHERE expr]

注意:事件执行完即释放,如立即执行事件,执行完后,事件便自动删除,多次调用事件或等待执行事件,才可以用上述命令查看到。

8、SQL语言(6)

8、SQL语言(6)

修改event

ALTER
[DEFINER = { user | CURRENT_USER }]
EVENT event_name
[ON SCHEDULE schedule]
[ON COMPLETION [NOT] PRESERVE]
[RENAME TO new_event_name]
[ENABLE | DISABLE | DISABLE ON SLAVE]
[COMMENT 'comment']
[DO event_body]
DISABLE ON SLAVE是一种事件调度器选项,用于指定当事件被复制到MySQL复制架构的从服务器时,是否禁用该事件的执行。简单来说,当在主服务器上启用了事件调度器并创建了事件时,可以使用DISABLE ON SLAVE选项来指定是否在从服务器上禁用该事件的执行。

8、SQL语言(6)

删除Event

DROP EVENT [IF EXISTS] event_name