【MySQL】MySQL概念解析(一)

一、MySQL变量

变量

系统变量
	全局变量
		作用域:MySQL服务器每次启动将为所有的全局变量赋初始值,所以全局变量作用范围不能跨重启
	会话变量
		作用域:针对于当前会话有效
	
自定义变量
	用户变量
		作用域:针对于当前会话有效
	局部变量
		作用域:仅仅在定义它的begin end中有效。应用在begin end中的第一句话!!!

系统变量
【1】说明:变量由系统提供,不是用户定义,属于服务器层面
【2】语法
1、查看所有的系统变量
show global variables;
show session variables;

2、查看指定的某个系统变量的值
select @@global.系统变量名;
select @@session.系统变量名;

3、为某个系统变量赋值
方式一:
set global 系统变量名 = 值
set session 系统变量名 = 值
方式二:
set @@global.系统变量名 = 值
set @@session.系统变量名 = 值

自定义变量
【1】说明:变量是用户自定义的,不是系统的
使用步骤:声明、赋值、使用(查看、比较、运算等)
【2】语法
用户变量
1、声明并初始化: 
set @用户变量名=值
set @用户变量名:=值
select @用户变量名:=值

2、赋值:
方式一:
set @用户变量名=值
set @用户变量名:=值
select @用户变量名:=值

方式二:
select 字段 into 用户变量名 from 表

3、使用:
select @用户变量名

局部变量
1、声明并初始化:
declare 变量名 类型
declare 变量名 类型 default 值
2、赋值:
set 局部变量名=值
select 字段 into 局部变量名 from 表
3、使用:
select 局部变量名

二、存储过程和函数

存储过程和函数:类似于Java中的方法
好处:
1、提高代码的重用性
2、简化操作
3、减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率

存储过程
含义:一组预先编译好的SQL语句的集合,理解成批处理语句
创建语法:
	create procedure 存储过程名(参数列表)
	BEGIN
		存储过程体(1组SQL语句)
	END
注意:
1、参数列表包含三部分:参数模式  参数名  参数类型
参数模式
IN:该参数可以作为输入,也就是该参数需要调用者传入值
OUT:该参数可以作为输出,也就是该参数可以作为返回值
INOUT:该参数即可以作为输入又可以输出

2、如果存储过程体仅仅只有一个SQL,BEGIN END可以省略
存储过程体中的每条SQL语句的结尾要求必须加分号
存储过程的结尾可以使用 delimiter 重新设置

语法:
delimiter 结束标记

调用语法
CALL 存储过程名(实参列表)

示例:
注意:因为在存储过程中可以有多个SQL语句,多个SQL语句之间区别使用 ; 进行区分,所以和正常的SQL结束标记冲突了,我们需要将正常SQL语句中的结束标记替换了,比如换成 $,即使用 delimiter $ 命令即可替换,此后该会话所有的操作都是以 $ 为结束符,例如: show table $ 、show databases $

delimiter $

【1】创建并调用存储过程
CREATE PROCEDURE myp1()
BEGIN
    DROP TABLE IF EXISTS `boys`;
    DROP TABLE IF EXISTS `girls`;
    CREATE TABLE boys(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(10) NOT NULL)CHARSET=utf8;
    CREATE TABLE girls(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(10) NOT NULL)CHARSET=utf8;
    INSERT INTO boys VALUES(NULL,'孙策'),(NULL,'周瑜'),(NULL,'刘备'),(NULL,'曹丕');
    INSERT INTO girls VALUES(NULL,'小乔'),(NULL,'大乔'),(NULL,'孙尚香'),(NULL,'甄姬');
END $

CALL myp1()$

---------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE PROCEDURE myp2(IN boyName VARCHAR(20),IN girlName VARCHAR(20))
BEGIN
	INSERT INTO boys VALUES(NULL,boyName);
	INSERT INTO girls VALUES(NULL,girlName);
END $

CALL myp2('吕布','貂蝉')$
---------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE PROCEDURE myp3(IN id INT,OUT boyName VARCHAR(20))
BEGIN
	SELECT b.name INTO boyName
	FROM boys b
	WHERE  b.id = id;
END $

CALL myp3(1,@resultName)$
SELECT @resultName$
---------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE PROCEDURE myp4(IN id INT,OUT id INT,OUT boyName VARCHAR(20))
BEGIN
	SELECT b.name,b.id INTO boyName,id
	FROM boys b
	WHERE  b.id = id;
END $

CALL myp4(1,@name,@id)$
SELECT @name,@id$
---------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE PROCEDURE myp5(INOUT a INT,INOUT b INT)
BEGIN
	set a = a * 2;
	set b = b * 2;
END $

set @m = 1 $
set @n = 2 $
call myp5(@m,@n) $
select @m,@n $

如果出现字符集错误,可以使用 set names gbk; 试试


【2】删除存储过程
语法:drop procedure 存储过程名

【3】查看存储过程的信息
语法:show create procedure 存储过程名

【4】练习
1、创建存储过程或函数,实现传入一个日期,格式化成 xx年xx月xx日并返回
DROP PROCEDURE procedure_test_1 $
CREATE PROCEDURE procedure_test_1(IN date_time DATETIME,OUT str_datetime VARCHAR(50))
BEGIN
 SELECT DATE_FORMAT(date_time,"%y年%m月%d日") INTO str_datetime;
END $

CALL procedure_test_1(NOW(),@str_datetime) $
SELECT @str_datetime $;

2、创建存储过程或函数,根据传入的条目数和其实索引,查询boys表的记录
DROP PROCEDURE procedure_test_2 $
CREATE PROCEDURE procedure_test_2(IN size INT,IN startIndex INT)
BEGIN
 SELECT * from boys limit startIndex,size;
END $

CALL procedure_test_2(2,1) $


函数
【1】和存储过程的区别
存储过程:可以有0个返回,也可以有多个返回,适合做批量插入、批量更新
函数:有且仅有1个返回,适合做处理数据后返回一个结果

【2】创建语法
create function 函数名(参数列表) returns 返回类型
BEGIN
	函数体
END	

注意:
1、参数列表包含两部分:
  参数名 参数类型
2、函数体:
  肯定会有 return语句,如果没有会报错,如果return语句没有放在函数体的最后也不报错,但不建议
3、函数体中仅有一句话,则可以省略 begin end
4、使用 delimiter 语句设置结束标记

【3】调用语法
select 函数名(参数列表)$

【4】练习
1、无参有返回
drop function myf1 $
CREATE FUNCTION myf1() RETURNS INT
BEGIN
 DECLARE temp INT DEFAULT 0; # 定义局部变量
 SELECT COUNT(*) INTO temp
 FROM boys;
 RETURN temp;
END $
select myf1() $

2、有参有返回
DROP FUNCTION myf2 $
CREATE FUNCTION myf2(id INT) RETURNS VARCHAR(20)
BEGIN
 set @temp = 0; #定义用户变量
 SELECT `name` INTO @temp
 FROM boys WHERE boys.id = id;
 RETURN @temp;
END $
SELECT myf2(2) $

【5】查看函数
show create function 函数名

【6】删除函数
drop function 函数名

三、流程控制结构

流程控制结构

顺序结构:程序从上往下依次执行
分支结构:程序选择某一条路径进行执行
循环结构:程序在满足一定条件时,重复执行一段代码


一、分支结构
1、if 函数
语法:
if (表达式1,表达式2,表达式3)
执行顺序:如果表达式1成立,则 if 函数返回表达式2的值,否则返回表达式3的值

2、case结构
语法:
情况1:
case 变量|表达式|字段 
when 要判断的值 then 返回的值1
when 要判断的值 then 返回的值2
...
ELSE 要返回的值
END

情况2:
case 
when 要判断的条件1 then 返回的值1
when 要判断的条件2 then 返回的值2
...
ELSE 要返回的值
END

3、if 结构 (只能应用在 begin end中)
语法:
if 条件1 then 语句1;
elseif 条件2 then 语句2;
...
else 语句n;
end if;

二、循环结构
分类:
while、loop、repeat

循环控制:
iterate 类似于 continue
leave 类似于 break

1、while:先判断后执行
语法:
【标签:】while 循环条件 do
	循环体;
end while	【标签】;

2、loop:没有条件的死循环
【标签:】loop
	循环体;
end loop 【标签】;

3、repeat:先执行后判断
语法:
【标签:】repeat
	循环体;
until 结束循环的条件
end repeat【标签】;	

4、练习
create procedure pro_while1(IN insertCount int)
begin
  declare i int default 1;
  while i <= insertCount do
	insert into boys values(null,concat("tom",i))
	set i = i + 1;
  end while;	
end $

call pro_while1(100) $

CREATE PROCEDURE pro_while2(IN insertCount INT)
BEGIN
  DECLARE i INT DEFAULT 1;
  a:WHILE i <= insertCount DO
	INSERT INTO boys VALUES(NULL,CONCAT("tom",i))
	IF i >= 20 THEN LEAVE a;
	END IF;
	SET i = i + 1;
  END WHILE a;	
END $

CALL pro_while2(100) $

CREATE PROCEDURE pro_while3(IN insertCount INT)
BEGIN
  DECLARE i INT DEFAULT 0;
  a:WHILE i <= insertCount DO
	SET i = i + 1;
	IF MOD(i,2) != 0 THEN ITERATE a;
	END IF;
	INSERT INTO boys VALUES(NULL,CONCAT("tom",i))
	
  END WHILE a;	
END $

CALL pro_while3(100) $

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章