mysql应用

mysql应用

一、变量

mysql本质是一种编程语言,需要很多变量来保存数据。mysql中很多属性控制都是通过mysql中固有的变量来实现的。

1 、系统变量

系统内部定义的变量,系统变量针对所有用户(mysql客户端)有效。

1、查看系统变量

--- 查看系统所有变量,
--- [like 'pattern'],进行条件筛选
show variables [like 'pattern'];
-- mysql允许用户使用select查询变量数据值(数据值)
-- 基本语法:select @@变量名;  -- 前提是需要知道系统变量名
select @@autocommit;

2、修改系统变量

-- 1、局部变量修改(会话级别):指针对自己客户端当前连接有效
基本语法:set 变量名 = 新值;
-- 2、全局修改:针对所有客户端,“所有时刻”都有效
基本语法:set global 变量名 = 值;  || set @@global.变量名 = 值;

2、会话变量

会话变量也称之为用户变量(由用户自定义),会话变量是跟mysql客户端绑定的,设置的变量,只针对当前用户使用的客户端生效。

-- 定义用户变量
基本语法:set @变量名 = 值;
set @name = 'hello world';
-- 查看自定义变量
select @name;

mysql中没有比较符号“==”,所以是用“=”代替比较符号,有时候在赋值时,会报错;mysql为了避免系统分不清是比较符号还是赋值符号:特定增加了一个变量赋值符号:" := "。

-- 专用赋值符号
set @name := 'hello world';

mysql是用于专门存储数据的,它允许将数据从表中取出来存储到变量中,查询得到的数据只能是一行,一个字段对应一个变量。

-- 1、赋值并查看赋值过程
select @变量名1 := 字段1 , @变量名2 := 字段2,..... from 数据表 where 条件;
-- 2、只赋值不查看过程
select 字段1 , 字段2, ...from 数据表 where条件 into @变量1, @变量2,....;

3、局部变量

作用范围在begin到end语句块之间。在该语句块里设置的变量,declare语句专门用于定义局部变量。

1、局部变量都是使用declare关键字声名,没有declare关键字,都不是局部变量。

2、局部变量declare语句一定是出现在begin与end之间。(begin~end是在大型语句块中使用,比如:函数/存储过 程/触发器)

3、声名语法:declare 变量名 数据类型 [属性];

二、流程结构

1、if分支

基本用法:

-- 1、使用select查询当中,当作一种条件进行判断
基本语法:if(条件,为true结果,为false结果);
select *,If(age>20,'符合','不符合') as judge from student;
-- as judge:结果列别名,'符合'与'不符合'的列名。
-- 2、在复杂的语句块中(函数/存储过程/触发器)
基本语法:
If 条件表达式 then 
	满足条件要执行的语句
End if;
-- 执行顺序:先执行条件表达式,进行判断,满足则执行then后的满足条件要执行的语句,end if;结束。(条件表达式中没有括号括起)

复合用法:

代码的判断存在两面性,两面都有相应的执行代码

基本语法:
If 条件表达式 then 
	满足条件要执行的代码
Else 
	不满足条件要执行的代码
	//这里不能使用else,else,如果需要细分,可以使用嵌套的形式
	IF 条件表达式 then 
		满足条件执行语句
     End if;
End if;

2、while循环

-- 基本语法:
While 条件 do 
	要执行的语句
End while;

1、结构标识符

结构表示符:为某些特定的结构进行命名,然后为了再某些地方,可以使用该名。

-- 基本语法:
标识名字:while 条件 do
	循环体
End while[标识名字];

-- 标识名字的存在主要是为控制循环

在mysql中的循环是没有continue和break关键字来终止循环执行的,它有自己的关键字替代。

iterate:迭代,以下的代码不执行,重新开始循环(continue)

leave:离开,终止整个循环体(break)

三、函数

mysql中的函数有两类:1、系统函数(内置函数);2、自定义函数。

不管是内置函数还是自定义函数,都是使用:select 函数名(参数列表); 来访问函数。

1、内置函数

1、字符串函数

Char_length():判断字符串的字符数;

Length():判断字符串的字节数(字符集有关);

Concat():连接字符串;

Instr():判断字符在目标的字符串中是否存在,返回其位置;不存在,返回0;

Lcase():全部小写;

Left():从左侧开始截取字符串,截取到指定位置;

Ltrim():消除左边对应的空格(位置超过长度,截取所有);

Mid():从中间指定位置开始截取,如果不指定截取长度,会截取到最后。

-- 示范
select char_length('您好中国'), length('您好');
select concat('您好','中国'), instr('hello!中国','中');

2、时间函数

Now():返回当前时间;

Curdate():返回当前日期;

Curtime():返回当前时间;

Datediff():判断两个日期之间的天数差距,其运算是一个减式;

Date_add(日期, interval 时间数字 type):进行时间的增加;

​ type:day/hour/minute…

Unix_timestamp():获取时间戳;

From_unixtime():将时间转换格式;

-- 演示
select curdate(),now(),curtime();
select datediff('2010-01-01','1995-09-28');
-- datediff():将上面的时间日期调换,会是一个负天数
select date_add('2010-01-01',interval 10 day);

3、数学函数

Abs():绝对值;

Ceiling():向上取整;

Floor():向下取整;

Pow():求指数,谁的多少次方;

Rand():产生随机数(0~1之间);

Round():四舍五入函数;

4、其他函数

Md5():对数据进行Md5加密(mysql中的MD5加密与其他的地方的MD5加密出来的内容是完全相同的,使用的相同的算法)

Version():获取版本号;

Database():显示当前数据库;

UUID():生成一个唯一的标识符(自增长),自增是单表唯一,UUID是整库(数据库唯一,空间唯一)

2、自定义函数

自定义函数:是用户自己根据需求定义的函数。

函数:实现某种功能的语句块(有多条语句组成)。

注意点:函数内的每条指令都是一个独立个体,需要符合语句定义定义规范,需要语句结束符分号 “ ;”。函数是一个整体,函数只有被调用的时候才会执行,在设计函数的时候,意味着整体不能被中断。

​ mysql一旦见到语句结束分号,就会终止执行

​ 解决方案:在定义函数前,修改临时的语句结束符;

​ 基本语法:delimiter 新符号;

使用完新的语句结束符之后,需要修改会原来的结束符:delimiter ;

1、创建函数

​ 自定义函数包含几要素:function 关键字,函数名,参数(形参和实参[可选]),确认函数返回值类型,函数体,返回值。

​ 基本语法:

​ 修改语句结束符

​ create function 函数名(形参) returns 返回值类型

​ begin

​ //函数体

​ return 返回值数据; //数据必须与结构体中的返回值类型一致

​ end

​ 语句结束符

​ 修改语句结束符(将结束符改回原来的)

-- 自定义函数:
-- 修改语句结束符
delimiter $$
create function my_func1() returns int 
begin 
	return 10;
end
-- 结束
$$
-- 将语句结束符改正回来
delimiter ;


------------------------------------------------------------------------------------------------
delimiter $$
create function my_function() returns int deterministic
begin 
	return 10;
end 
$$
delimiter ;
-- deterministic:告诉Mysql,信任我,方法不会修改数据,Mysql不再检查,即使修改了数据。这个时候要靠你信守承诺,否则后果自负。

2、查看函数

–查看所有:基本语法:show function status[like ‘pattern’];

–查看函数的创建语句:show create function 函数名;

3、调用函数

–自定义函数的调用方式和内置函数调用方式一样,select 函数名(实参列表);

4、删除函数

基本语法:drop function 函数名;

3、函数流程结构的案例

需求:从1开始,直到用户传入到对应的值为止,自动求和,凡是5的倍数都不要;

设计:

1、创建函数;

2、需要一个形参,确定要累加到什么位置;

3、需要定义一个变量来保存结果(局部变量,declare来声名,不是set);

4、内部需要一个循环来实现迭代累加

5、内部循环需要进行条件判断来控制5的倍数

-- 创建一个自动求和的函数
-- 修改语句结束符
delimiter $$
create function my_sum(end_value int ) returns int deterministic
begin
	declare result int default 0;
	declare i int default 1;
	mywhile:while i <= end_value do
		-- 判断
		if i%5 = 0 then
			set i = i+1;
			iterate mywhile;
		end if;
		-- 改变变量:累加加过1
		set result = result + i;
		set i = i+1;
	end while;
	-- 返回值
	return result;
end
$$
delimiter ;

-- 调用函数
select my_sum(100),my_sum(-100);

四、变量作用域

变量作用域:变量能够使用的区域范围

1、局部作用域

使用declare关键字来声名(在结构体内:函数/存储过程/触发器),仅在结构体内使用

declare关键字声名的变量没有任何符号修饰,就是普通的字符串,如果外部访问该变量,系统会自动认为是字段

2、会话作用域

用户自定义,使用@符号定义的变量,使用set关键字;

会话作用域:只在当前用户连接有效,只要在本连接之中,任何地方都可以使用(可以在内部结构,可以垮库);

3、全局作用域

所有的客户端,所有的连接都有效:使用全局符号来定义

set global 变量名 = 值;// set @@global.变量名 = 值;

五、存储过程

存储过程(Stored Procedure)是在大型的数据库系统中,一组为了完成特定的功能SQL语句集,存储在数据库中,经过第一次编译之后再次调用不用再次进行编译(效率高),用户通过指定存储过程的名字并给出参数(如果存储过程带有参数)来执行它。存储过程是数据库的一个重要对象(针对SQL编程)。

1、存储过程与函数区别

1、相同点

​ -1、存储过程与函数的目的都是为可重复地执行操作数据库的SQL语句的集合

​ -2、存储过程与函数,都是一次编译,后续执行。

2、不同点

​ -1、标识符不同:存储过程标识符为:procedure ;函数为:function

​ -2、函数中有返回值,且必须返回;存储过程没有返回值;

​ -3、过程没有返回值类型,不能将结果直接赋给变量;函数有返回值,调用时,除了select语句,必须将返回

​ 赋给变量;

​ -4、函数可以在select语句中使用,存储过程不能;

2、存储过程的操作

1、创建存储过程

-- 基本语法
create procedure 过程名称([参数列表])
begin 
	过程体
end 
结束符

-- 简单的存储过程
create procedure my_pro()
	select *from student;

-- 复杂存储过程
delimiter $$
create procedure my_procedure()
begin 
	-- 求1到100的和
	declare i int default 1;
	-- declare sum int default 0; --局部变量
	set @sum = 0;  -- 会话变量
	while i<=100 do 
		set @sum = @sum + i;
		set i = i+1;
	end while;
	-- 显示结果,将结果给外部
	select @sum;
end 
$$
delimiter ;

2、查看存储过程

存储过程的查看与查看函数方式是一样;除了关键字

查看全部存储过程:show procedure status [‘like pattern’];

查看存储过程创:show create procedure 过程名字;

3、调用存储过程

过程:没有返回值,不能使用select调用;

调用过程专门语法:call 过程名 ([实参列表]);

-- 调用过程
call my_procedure();

4、删除存储过程

基本语法:drop procedure 过程名;

-- 删除过程
drop procedure my_pro,my_procedure;

3、存储过程的形参类型

存储过程允许提供参数(形参与实参),存储过程的参数与函数的参数一样,需要指定参数类型;

存储过程对参数有额外的要求:自己的参数类型。

in 参数从外部传入到存储过程内部使用,可以是直接数据也可以是保存数据的变量
out 参数从过程里面把数据保存到变量中,交给外部使用,传入的必须是变量;传入的out变量在外部有值,在进入过程后的第一件事就是将变量的值清空,设为null;
Inout 数据可以从外部传入到过程内部使用,同时也可以内部操作之后,将数据返还给外部使用。
-- 创建三个外部变量
set @n1 = 1;
set @n2 = 2;
set @n3 = 3;
-- 创建过程
delimiter $$
create procedure my_procedure(in int_1 int,out int_2 int,inout int_3 int )
begin 
	-- 查看三个变量的值
	select @n1,@n2,@n3;
	-- 修改三个变量的值
	set int_1 = 10;
	set int_2 = 100;
	set int_3 = 1000;
	select int_1,int_2,int_3;
	-- 查看会话变量
	select @n1,@n2,@n3;
	-- 修改会话变量
	set @n1 = 'a';
	set @n2 = 'b';
	set @n3 = 'c';
	select @n1,@n2,@n3;
end
$$
delimiter ;

-- 调用过程
call my_procedure(@n1,@n2,@n3);

六、触发器

1、基本概念:

触发器是一种特殊类型的存储过程。触发器主要通过事件进行触发而被执行的。它不同与存储过程,存储过程可以通过存储过程名称来调用。

触发器:trigger ,是一种非常接近于JavaScript中的事件知识,提前给某张表的所有记录(行)绑定一段代码,如果该行的操作满足条件(触发),这段提前准备好的代码就会被执行。

2、作用

1、可在写入数据表前,强制检验或转换数据(保证数据安全)。

2、触发器发生错误时,异常的结果会被撤销(如果触发器执行错误,前面用户已经执行成功的操作也会被撤销,类似于事务管理)。

3、部分数据库管理系统可以针对数据定义语言(DDL)使用触发器,被称为DDL触发器。

4、可依照特定情况,替换异动的指令(INSTEAD OF)。(mysql不支持)

3、触发器优缺点

1、优点:触发器可以通过数据中的相关表实现级联更改,保证数据安全。

2、缺点:对触发器过分的依赖,会影响数据库的结构,同时增加了维护的复杂性;造成数据在程序面不可控。

4、触发器操作

1、创建触发器

-- 创建触发器基本语法:
create trigger 触发器名字 触发时机 触发事件 on 表 for each row 
begin

end 

-- 1、 触发器对象:on 表 for each row, 触发器绑定实质是表中的所有行,因此当每一行发生指定的改变时,就会触发触发器
-- 2、 触发时机:每张表对应的行都会有不同的状态,当SQL指令发生的时候,都会令行中的数据发生改变,每一行都会有两种状态:数据操作前和操作后
-- Before :在表中数据发生改变前的状态
-- After :在表中数据发生改变后的状态
-- 3、触发事件:mysql中触发器针对的目标的数据发生改变,对应的操作只有写的操作(增删改)


注意事项:一张表中,每一个触发时机绑定的触发事件对应的触发器类型只能是一个:一张表只能对应一个after insert 触发器。

因此一张表中的触发器最多只有6个:after insert , after update, after delete , before insert ,before update ,before delete ;

-- 需求:有两张表,一张是商品表,一张是订单表(包含商品ID),每次生成订单,商品表中的对应库存就会发生变化;

-- 创建两张表
create table my_goods(
	id int primary key auto_increment,
    name varchar(20) not null,
    inv int     
)charset utf8;
create table my_orders(
	id int primary key auto_increment,
    good_id int not null,
    good_num int not null
)charset utf8;

insert into my_goods values (null,'手机',1000),(null,'电脑',500),(null,'游戏机',100);
-- 创建触发器
-- 修改结束符
delimiter $$
create trigger after_insert_order_t after insert on my_orders for each row
begin 
	-- 更新商品库存
	update my_goods set inv = inv-1 where id = 1;	
end 
$$
delimiter ;

-- after_insert_order_t:触发器名
-- after:触发时机,
-- insert:触发事件
-- on my_orders for each row:触发对象
-- 定义了一个名为after_insert_order_t的触发器,此触发器是在my_orders表的insert(插入)事件之后被触发的(after),触发后改变的状态是my_goods的库存数量。

2、查看触发器

– 1、查看全部触发器:show triggers;

–2、查看触发器的创建语句:show create trigger 触发器名;

3、删除触发器

基本语法:drop trigger 触发器名;

-- 删除触发器
drop trigger after_insert_order_t;

5、触发器的应用

1、触发器记录关键字:old 、new

触发器针对的是数据表中的每条记录(每行),每行在数据操作前后都有一个对应的状态,触发器在执行之前就将对应状态获悉到了,将没有操作之前的数据状态都保存到old关键字中,而操作后的数据状态放在new中。

触发器中,可以通过old和new获取绑定表中的对应记录数据

基本语法:关键字.字段名;

但old和new,并不是所有的触发器都有;

-- 自动扣除商品库存
delimiter $$
create trigger a_i_o_t after insert on my_orders for each row
begin 
	-- 更新商品的库存:new代表新增的订单
	-- update my_goods set inv = inv -? where id =?;
	update my_goods set inv = inv - new.good_num  where id =new.good_id;
end 
$$
delimiter ;
-- 判断商品库存
delimiter $$
create trigger b_i_o_t before insert on my_orders for each row
begin
	-- 取出库存数据,进行判断
	select inv from my_goods where id = new.good.id into @inv;
	-- 判断
	if @inv < new.good_num then
		-- 主动出错
		insert into xxx values('xxx');
	end if;
end
$$
delimiter ;

猜你喜欢

转载自blog.csdn.net/weixin_43220261/article/details/83317625