变量
系统变量
全局变量
作用域: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) $