首页 > 数据库 >MySQL之视图、触发器、存储过程、函数和流程控制

MySQL之视图、触发器、存储过程、函数和流程控制

时间:2024-03-03 19:22:51浏览次数:25  
标签:insert 触发器 01 create cmd 视图 time MySQL

视图

  • 什么是视图
视图就是通过查询得到一张虚拟表,然后保存下来,下次可以直接使用
其实视图也是表
  • 为什么要用视图
如果要频繁的操作一张虚拟表(拼表组成的),你就可以制作成视图,后续直接操作
  • 如何操作
# 固定语法
create view 表名 as 虚拟表的查询SQL语句

# 具体操作
create view teacher2course as
select * from teacher inner join course
on teacher.id = course.teacher_id;
  • 注意
1. 创建视图在硬盘上只会有表结构,没有表数据(数据还是来自于之前的表)
2. 视图一般只用来查询,里面的数据不要继续修改,可能会影响真正的表
  • 视图到底使用频率高不高?
不高,当你创建了很多视图之后,会造成表的不好维护
了解即可,基本不用!!!

触发器

在满足对表数据进行增、删、改的情况下,自动触发的功能。

使用触发器可以帮助我们实现监控、日志、自动处理异常等等。

触发器可以在六种情况下自动触发,增前、增后、删前、删后、改前、改后

基本语法结构

create trigger 触发器的名字 before/after insert/update/delete on 表的名字
for each row
begin
	SQL语句
end

# 具体使用,针对触发器的名字,我们通常需要做到见名知意
# 针对增
create trigger tri_before_insert_t1 before insert on t1
for each row
begin
	SQL语句
end
create trigger tri_after_insert_t1 after insert on t1
for each row
begin
	SQL语句
end

# 针对删和针对改,与上述格式一致

ps:修改MySQL默认的语句结束符,只作用于当前窗口
	delimiter $$ 将默认的结束符号由;变成$$
	delimiter ;
	
# 案例
create table cmd (
	id int primary key auto_increment,
    user char(32),
    priv char(10),
    cmd char(64),
    sub_time datetime, # 提交时间
    success enum('yes','no') # 0代表执行失败
);

create table errlog(
	id int primary key auto_increment,
    err_cmd char(64),
    err_time datetime
);

# 需求
当cmd表中的记录success字段是no,那么就触发触发器的执行去errlog表中插入数据
# NEW指代的就是一条条数据对象
delimiter $$ 
create trigger tri_after_insert_cmd after insert on cmd
for each row
begin 
	if NEW.success = 'no' then
		insert into errlog(err_cmd,err_time)
values(NEW.cmd,NEW.sub_time);
	end if;
end $$
delimiter ;

# 朝cmd表插入数据
insert into cmd(user,priv,cmd,sub_time,success) 
values
	('xiao','0123','ls -l /etc',NOW(),'yes'),
	('xiao','0123','cat /etc/passwd',NOW(),'no'),
	('xiao','0123','useradd xxx',NOW(),'no'),
	('xiao','0123','ps aux',NOW(),'yes');
	
# 模拟日志功能结果
select * from cmd;
+----+------+------+-----------------+---------------------+---------+
| id | user | priv | cmd             | sub_time            | success |
+----+------+------+-----------------+---------------------+---------+
|  1 | xiao | 0123 | ls -l /etc      | 2024-01-29 16:15:31 | yes     |
|  2 | xiao | 0123 | cat /etc/passwd | 2024-01-29 16:15:31 | no      |
|  3 | xiao | 0123 | useradd xxx     | 2024-01-29 16:15:31 | no      |
|  4 | xiao | 0123 | ps aux          | 2024-01-29 16:15:31 | yes     |
+----+------+------+-----------------+---------------------+---------+
select * from errlog;
+----+-----------------+---------------------+
| id | err_cmd         | err_time            |
+----+-----------------+---------------------+
|  1 | cat /etc/passwd | 2024-01-29 16:15:31 |
|  2 | useradd xxx     | 2024-01-29 16:15:31 |
+----+-----------------+---------------------+

# 删除触发器
drop trigger tri_after_insert_cmd;

存储过程

存储过程就类似于python中的自定义函数

它的内部包含了一系列可执行的SQL语句,存储过程存放于MySQL服务端中,你可以直接通过调用存储过程触发内部SQL语句的执行

基本使用

create procedure 存储过程的名字(形参1,形参2,....)
begin 
	sql代码
end

# 调用
call 存储过程的名字();

三种开发模式

  • 第一种

应用程序:程序员写代码开发
MySQL:提前编写好存储过程,供应用程序调用

好处:开发效率提升了,执行效率也上去了
缺点:考虑到人为因素,跨部门沟通的问题,后续的存储过程的扩展性差

  • 第二种

应用程序:程序员自己写代码开发之外,涉及到数据库操作也自己动手写

好处:扩展性很高
缺点:开发效率降低,编写SQL语句太过繁琐,而且后续还需要考虑SQL优化的问题

  • 第三种

应用程序:只写程序代码,不写SQL语句,基于别人写好的操作MySQL的python的框架直接调用操作即可。

优点:开发效率比上面两种都高
缺点:语句的扩展性差,可能会出现效率低下的问题

总结

第一种基本不用,一般都是第三种,出现效率问题再动手写sql

存储过程具体演示

delimiter $$
create procedure p1(
	in m int,  # in 表示只进不出,m不能返回出去
    in n int,
    out res int  # out表示该形参可以返回出去
)
begin 
	select name from teacher where id>m and id<n;
	set res=777;  # 将res变量修改,用来标识当前的存储过程代码确实执行了
end $$
delimiter ;

call p1(1,2,5);  # 报错,ERROR 1414 (42000): OUT or INOUT argument 3 for routine day45.p1 is not a variable or NEW pseudo-variable in BEFORE trigger
# 针对形参res,不能直接传数据,应该先传一个变量名
# 定义变量
set @ret = 10;
# 查看变量对应的值
select @ret;
# 再次调用
call p1(1,2,@ret);

在pymysql模块中如何调用存储过程呢?

import pymysql

conn = pymysql.connect(
    host='127.0.0.1',
    port=3306,
    user='root',
    password='111111',
    database='day45',
    charset='utf8',  # 编码千万不要加-
    autocommit=True  # 自动提交
)  # 链接数据库
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
# 调用存储过程
cursor.callproc('p1', (1, 2, 5))
"""
@_p1_0=1
@_p1_1=2
@_p1_2=5
"""
print(cursor.fetchall())
cursor.execute('select @_p1_2;')
print(cursor.fetchall())  # [{'@_p1_2': 777}]

函数

跟存储过程是有区别的,存储过程是自定义函数,函数就类似于内置函数。

# 示例:
create table blog(
	id int primary key auto_increment,
    name char(32),
    sub_time datetime
);

insert into blog(name,sub_time)
values
	('第1篇','2015-02-01 11:31:22'),
	('第2篇','2015-05-06 14:51:12'),
	('第3篇','2016-02-01 09:31:53'),
	('第4篇','2016-02-01 19:23:45'),
	('第5篇','2016-02-01 04:54:14'),
	('第6篇','2017-02-01 21:52:56'),
	('第7篇','2017-02-01 22:08:32'),
	('第8篇','2018-02-01 09:05:32'),
	('第9篇','2018-02-01 08:18:22');

select date_format(sub_time,'%Y-%m'),count(id) from blog group by date_format(sub_time,'%Y-%m');

流程控制

# if 判断
delimiter //
create procedure proc_if()
begin
	declare i int default 0;
	if i = 1 then 
		select 1;
	elseif i = 2 then
		select 2;
	else
		select 7;
       end if;
end //
delimiter ;

# while循环
delimiter //
create procedure proc_while()
begin
	declare num int;
	set num = 0;
	while num < 10 do
		select 
			num;
		set num = num + 1;
	end while;
end //
delimiter ;

标签:insert,触发器,01,create,cmd,视图,time,MySQL
From: https://www.cnblogs.com/xiao01/p/18050502

相关文章

  • 从零开始学Spring Boot系列-集成MySQL
    在SpringBoot中集成MySQL是为了让开发者能够轻松地与MySQL数据库进行交互。本篇文章将指导你如何在SpringBoot3.2.3项目中使用Gradle来集成MySQL。在此之前,我们需要在Ubuntu22.04上安装MySQL8作为我们的数据库服务器。安装MySQL8本文是在wsl2上的Ubuntu22.04上安装MySQL8.......
  • MySQL之筛选和过滤条件
    开局第一步:创表createdatabaseday03;useday03;createtableemp( idintnotnulluniqueauto_increment,namevarchar(20)notnull,sexenum('male','female')notnulldefault'male',ageint(3)unsignednotnulldefau......
  • MySQL之约束条件
    表完整性约束介绍:约束条件与数据类型的宽度一样,都是可选参数作用:用于保证数据的完整性和一致性主要分为:DEFAULT为该字段设置默认值NOTNULL标识该字段不能为空UNIQUEKEY(UK)标识该字段的值是唯一的AUTO_INCREMENT标识该字段的值自动增长(整数类型,而且为主......
  • Linux安装Docker并搭建MySql、Redis、RabbitMQ
    1.1安装docker(1)删除老版本sudoyumremovedocker\docker-client\docker-client-latest\docker-common\docker-latest\docker-latest-logrotate\......
  • MySQL之基本数据类型
    数据类型:类型类型举例整数类型TINYINT、SMALLINT、MEDIUMINT、INT(或INTEGER)、BIGINT浮点类型FLOAT、DOUBLE定点数类型DECIMAL位类型BIT日期时间类型YEAR、TIME、DATE、DATETIME、TIMESTAMP文本字符串类型CHAR、VARCHAR、TINYTEXT、TEXT、MEDIUMT......
  • Docker启动MySQL容器自动停止问题
    可能是mysql使用的内存过多,导致系统杀死了对应的进程mysql启动后设置限制内存在宿主机任意位置下:vimdocker.cnf写入:skip-host-cacheskip-name-resolveperformance_schema_max_table_instances=400table_definition_cache=400table_open_cache=256performance_......
  • MySQL安装
    下载mysql官网地址:https://dev.mysql.com/downloads/mysql/配置解压文件解压下载好的压缩文件解压后目录中可能没有my.ini文件,自己创建一个使用记事本打开my.ini文件[mysqld]port=3306basedir=C:\ProgramFiles\MySQLdatadir=C:\ProgramFiles\MySQL\Datamax......
  • 新电脑装编程配置(jdk、MySQL、navicat、idea、Maven、gitee、环境配置)
    一、JDK(java运行环境,不安装不能在自己电脑上运行java语言)1.打开安装包     2.选择安装目录(建议选择非系统盘)      3.安装JRE(最好和JDK分开文件夹、建议选择非系统盘)     4.提示安装成功     配置环境变量:JAVA......
  • MySQL之存储引擎
    什么是存储引擎数据库存储引擎是数据库底层软件组织,数据库管理系统使用数据引擎进行创建、查询、更新和删除数据。日常生活中文件格式有很多种,并且针对不同的文件格式会有对应不同存储方式和处理机制(txt、pdf、word、mp4等等)不同的存储引擎提供不同的存储机制、索引机制......
  • MySQL之SQL语句+严格模式
    SQL使用规范在数据库管理系统中,SQL语句关键字不区分大小写(但建议用大写),参数区分大小写。建议命令大写,数据库名、数据表名、字段名统一小写,如数据库名、数据表名、字段名与关键字同名,使用反引号圈起来,避免冲突。SQL语句可单行或多行书写,默认以英文分号(;)结尾,关键词不能跨多......