#变量
/*
系统变量
全局变量
会话变量
自定义变量
用户变量
局部变量
*/
#一,系统变量
#说明:变量由系统提供,不是用户定义的,属于服务器层面
#使用语法
#1,查看所有系统变量
SHOW GLOBAL VARIABLES
#2 查看满足条件的部分系统变量
SHOW GLOBAL VARIABLES LIKE "%char%"
#3 查看指定的某个系统变量的值
SELECT @@系统变量名
#4 为某个系统变量赋值
SET GLOBAL 系统变量名 = 值
SET @@GLOBAL 系统变量名 = 值
#注意
#如果是全局级别,则需要加global 如果是会话级别,则需要加session,不写默认session
#1 全局变量
SHOW GLOBAL VARIABLES
#2 会话变量
/*
作用域:仅仅针对于当前会话(连接)有效
*/
#查看所有会话变量
SHOW SESSION VARIABLES
#查看部分
SHOW SESSION VARIABLES LIKE "%char%"
#查看指定会话变量
SELECT @@character_set_client
#为某个会话变量赋值
SET @@character_set_client=值
SET SESSION character_set_client=值
#二 自定义变量
/*
说明: 变量是用户自定义的,不是由系统提供的
使用步骤
声明
赋值
使用(查看,比较,运算)
*/
#1用户变量
/*
作用域:针对于当前会话(连接)有效
应用在任何地方
*/
#赋值操作符= :=
#声明并初始化
SET @用户变量名=值
SET @ 用户变量名:=值
SELECT @ 用户变量名:=值
#赋值(更新用户变量的值)
方式一
SET @用户变量名=值
SET @ 用户变量名:=值
SELECT @ 用户变量名:=值
方式二
SELECT 字段 INTO 变量名
FROM 表
SET @name:=100
SELECT COUNT(*) INTO @count
FROM `employees`
#3 查看变量值
SELECT @count
#2 局部变量
/*
作用域:仅仅在定义它的begin end 中有效
*/
#声明
DECLARE 变量名 类型
DECLARE 变量名 类型 DEFAULT 值
#赋值
方式一
SET 变量名=值
SET 变量名:=值
SELECT 变量名:=值
方式二
SELECT 字段 INTO 变量名
FROM 表
#使用
SELECT 局部变量名
对比用户变量和局部变量
作用域 定义和使用位置 用法
用户变量 当前会话 会话任何位置 必须加@ 不必声明类型
局部变量 BEGIN END 中 只能在begin end中,且为第一句话 一般不用加@,需要声明类型
#案例:声明两个变量并赋初始值,求和并打印
#用户变量
SET @a=1;
SET @b=2;
SET @sum=@a+@b;
SELECT @sum;
#局部变量
DECLARE m INT DEFAULT 1
DECLARE n INT DEFAULT 2
DECLARE SUM;
SET SUM=m+n
SELECT SUM
#存储过程和函数
/*
存储过程和函数:类似于JAVA中的方法
*/
#存储过程
/*
含义:一组预先编译好的sql语句的集合
1 提高代码的重用性
2 简化操作
3 减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率
*/
#一 创建语法
CREATE PROCEDURE 存储过程名(参数列表)
BEGIN
方法体
END
/*
注意 :
1 参数列表包含三部分
参数模式 参数名 参数类型
参数模式:
in 该参数可以作为输入,也就是该参数需要调用方法传入值
out 该参数可以作为输出,也就是该参数可以作为返回值
inout 该参数可以作为输入输出,也就是该参数需要调用方法传传入值,也可以作为返回值
*/
/*
2 如果存储过程体仅仅只有一句话,bengin end 可以省略
存储过程中的每条sql语句结尾都要加分号
存储过程的结尾采用delimiter
语法:
delimiter 结束标记
*/
#二 调用语法
CALL 存储过程名(实参列表)
#1 空参列表
# 插入admin表中5条记录
SELECT * FROM`admin`
DELIMITER $
CREATE PROCEDURE ins()
BEGIN
INSERT INTO admin(`username`,`password`)
VALUES('niu','123');
END $
CALL ins()$
#带in模式参数的存储过程
#创建存储过程实现根据女神名,查询对应的男神信息
DELIMITER $
CREATE PROCEDURE pp(IN beautyName VARCHAR(20))
BEGIN
SELECT boys.*
FROM `boys`
RIGHT JOIN `beauty`
ON `boys`.`id`=`beauty`.`boyfriend_id`
WHERE `beauty`.`name`= beautyName;
END$;
CALL pp('dddaa');
#创建存储过程实现用户是否登录成功
DELIMITER $;
CREATE PROCEDURE p1(IN `username` VARCHAR(10),IN `password` VARCHAR(10))
BEGIN
DECLARE c INT DEFAULT 0;
SELECT COUNT(*) INTO c
FROM `admin`
WHERE `admin`.`password`=`password`
AND `admin`.`username`=`username`;
SELECT IF(c>0,'1','0');
END $;
CALL p1('1','2');
#创建带out 根据女神名,返回对应的男神名
DELIMITER $;
CREATE PROCEDURE myp7(IN beautyName VARCHAR(20),OUT boyName VARCHAR(20),OUT usercp INT)
BEGIN
SELECT boys.boyname ,boys.usercp INTO boyname,usercp
FROM boys
RIGHT JOIN
beauty b ON b.boyfriend_id = boys.id
WHERE b.name=beautyName ;
END $;
SET @nam
#4 创建带inout模式参数的存储过程
#传入a和b 两个值最终a和b都翻倍并返回
DELIMITER $;
CREATE PROCEDURE p3(INOUT a INT,INOUT b INT)
BEGIN
SET a=a*2;
SET b=b*2;
END $;
CALL p3(@a,@b);
SELECT @a,@b;
#二 删除存储过程
#语法 drop procedure 存储过程名
DROP PROCEDURE p1;
#三查看存储过程的信息
SHOW CREATE PROCEDURE p1;
#函数
/*
含义:一组预先编译好的sql语句的集合
1 提高代码的重用性
2 简化操作
3 减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率
区别:
存储过程可以有0个返回,也可以有多个返回
函数:有且仅有1个返回
*/
#一 创建语法
/*
create function 函数名(参数列表)returns 返回类型
begin
函数体
end
注意 参数列表包含两部分 参数名 参数类型
函数:肯定会有return语句 ,如果没有会报错
函数只有一句话可以省略 begin end
使用delimiter语句设置标记
*/
#二 调用语法
SELECT 函数名(参数列表)
#无参有返回
#返回员工个数
SET GLOBAL log_bin_trust_function_creators=TRUE;
DELIMITER $;
CREATE FUNCTION c() RETURNS INT
BEGIN
DECLARE c INT DEFAULT 0;
SELECT COUNT(*) INTO c
FROM `employees`;
RETURN c;
END$;
SELECT c()
#2 有参有返回
#根据员工名返回他的工资
DELIMITER $;
SET GLOBAL log_bin_trust_function_creators=TRUE;
CREATE FUNCTION s(nam VARCHAR(50)) RETURNS DOUBLE
BEGIN
SET @m=0;
SELECT `salary` INTO m
FROM `employees`
WHERE `last_name`=nam;
RETURN m;
END$;
# 三,查看函数
SHOW CREATE FUNCTION 函数名
#四, 删除函数
DROP FUNCTION 函数名
#流程控制结构
/*
顺序、分支、循环
*/
#一、分支结构
#1.if函数
/*
语法:if(条件,值1,值2)
功能:实现双分支
应用在begin end中或外面
*/
#2.case结构
/*
语法:
情况1:类似于switch
case 变量或表达式
when 值1 then 语句1;
when 值2 then 语句2;
...
else 语句n;
end
情况2:
case
when 条件1 then 语句1;
when 条件2 then 语句2;
...
else 语句n;
end
应用在begin end 中或外面
*/
#3.if结构
/*
语法:
if 条件1 then 语句1;
elseif 条件2 then 语句2;
....
else 语句n;
end if;
功能:类似于多重if
只能应用在begin end 中
*/
#案例1:创建函数,实现传入成绩,如果成绩>90,返回A,如果成绩>80,返回B,如果成绩>60,返回C,否则返回D
CREATE FUNCTION test_if(score FLOAT) RETURNS CHAR
BEGIN
DECLARE ch CHAR DEFAULT 'A';
IF score>90 THEN SET ch='A';
ELSEIF score>80 THEN SET ch='B';
ELSEIF score>60 THEN SET ch='C';
ELSE SET ch='D';
END IF;
RETURN ch;
END $
SELECT test_if(87)$
#案例2:创建存储过程,如果工资<2000,则删除,如果5000>工资>2000,则涨工资1000,否则涨工资500
CREATE PROCEDURE test_if_pro(IN sal DOUBLE)
BEGIN
IF sal<2000 THEN DELETE FROM employees WHERE employees.salary=sal;
ELSEIF sal>=2000 AND sal<5000 THEN UPDATE employees SET salary=salary+1000 WHERE employees.`salary`=sal;
ELSE UPDATE employees SET salary=salary+500 WHERE employees.`salary`=sal;
END IF;
END $
CALL test_if_pro(2100)$
#案例1:创建函数,实现传入成绩,如果成绩>90,返回A,如果成绩>80,返回B,如果成绩>60,返回C,否则返回D
CREATE FUNCTION test_case(score FLOAT) RETURNS CHAR
BEGIN
DECLARE ch CHAR DEFAULT 'A';
CASE
WHEN score>90 THEN SET ch='A';
WHEN score>80 THEN SET ch='B';
WHEN score>60 THEN SET ch='C';
ELSE SET ch='D';
END CASE;
RETURN ch;
END $
SELECT test_case(56)$
#二、循环结构
/*
分类:
while、loop、repeat
循环控制:
iterate类似于 continue,继续,结束本次循环,继续下一次
leave 类似于 break,跳出,结束当前所在的循环
*/
#1.while
/*
语法:
【标签:】while 循环条件 do
循环体;
end while【 标签】;
联想:
while(循环条件){
循环体;
}
*/
#2.loop
/*
语法:
【标签:】loop
循环体;
end loop 【标签】;
可以用来模拟简单的死循环
*/
#3.repeat
/*
语法:
【标签:】repeat
循环体;
until 结束循环的条件
end repeat 【标签】;
*/
#1.没有添加循环控制语句
#案例:批量插入,根据次数插入到admin表中多条记录
DROP PROCEDURE pro_while1$
CREATE PROCEDURE pro_while1(IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i<=insertCount DO
INSERT INTO admin(username,`password`) VALUES(CONCAT('Rose',i),'666');
SET i=i+1;
END WHILE;
END $
CALL pro_while1(100)$
/*
int i=1;
while(i<=insertcount){
//插入
i++;
}
*/
#2.添加leave语句
#案例:批量插入,根据次数插入到admin表中多条记录,如果次数>20则停止
TRUNCATE TABLE admin$
DROP PROCEDURE test_while1$
CREATE PROCEDURE test_while1(IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 1;
a:WHILE i<=insertCount DO
INSERT INTO admin(username,`password`) VALUES(CONCAT('xiaohua',i),'0000');
IF i>=20 THEN LEAVE a;
END IF;
SET i=i+1;
END WHILE a;
END $
CALL test_while1(100)$
#3.添加iterate语句
#案例:批量插入,根据次数插入到admin表中多条记录,只插入偶数次
TRUNCATE TABLE admin$
DROP PROCEDURE test_while1$
CREATE PROCEDURE test_while1(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 admin(username,`password`) VALUES(CONCAT('xiaohua',i),'0000');
END WHILE a;
END $
CALL test_while1(100)$
/*
int i=0;
while(i<=insertCount){
i++;
if(i%2==0){
continue;
}
插入
}
*/
CREATE PROCEDURE p4(IN username VARCHAR(20),IN PASSWORD VARCHAR(20))
BEGIN
INSERT INTO `admin`(`username`,`password`)
VALUES(username,PASSWORD);
END $;
CALL p4('niu','123456');
DELIMITER $;
CREATE PROCEDURE p1(IN i INT,OUT nam VARCHAR(20),OUT phon VARCHAR(20))
BEGIN
SELECT `name`,`phone` INTO nam,phon
FROM `beauty`
WHERE `id`=i;
END $;
CALL p1(1,@nam,@phon);
SELECT @nam,@phon;
DROP PROCEDURE p3
DELIMITER $;
CREATE PROCEDURE p3(IN mydate DATETIME,OUT strdate VARCHAR(50))
BEGIN
SELECT DATE_FORMAT(mydate,'%y年%m月%d日') INTO strdate;
END;