/***
数据库存储过程控制流程篇
**
delimiter
c
r
e
a
t
e
p
r
o
c
e
d
u
r
e
h
e
l
l
o
p
r
o
c
e
d
u
r
e
(
)
b
e
g
i
n
s
e
l
e
c
t
′
h
e
l
l
o
′
;
e
n
d
create procedure hello_procedure() begin select 'hello'; end
createprocedurehelloprocedure()beginselect′hello′;end
call hello_procedure();
delimiter
c
r
e
a
t
e
p
r
o
c
e
d
u
r
e
s
p
v
a
r
(
)
b
e
g
i
n
d
e
c
l
a
r
e
v
a
r
n
a
m
e
v
a
r
c
h
a
r
(
32
)
d
e
f
a
u
l
t
′
S
F
′
;
s
e
t
v
a
r
n
a
m
e
=
′
U
G
′
;
s
e
l
e
c
t
v
a
r
n
a
m
e
;
e
n
d
create procedure sp_var() begin declare var_name varchar(32) default 'SF'; set var_name='UG'; select var_name; end
createprocedurespvar()begindeclarevarnamevarchar(32)default′SF′;setvarname=′UG′;selectvarname;end
call sp_var()
delimiter
c
r
e
a
t
e
p
r
o
c
e
d
u
r
e
t
e
s
t
A
l
l
(
)
b
e
g
i
n
s
e
t
@
s
e
t
a
l
l
=
′
1
2
′
;
e
n
d
create procedure test_All() begin set @set_all='12'; end
createproceduretestAll()beginset@setall=′12′;end
call test_All()
s
e
l
e
c
t
@
s
e
t
a
l
l
select @set_all
select@setall
DELIMITER
C
R
E
A
T
E
P
R
O
C
E
D
U
R
E
t
e
s
t
A
l
l
2
(
)
B
E
G
I
N
s
e
l
e
c
t
u
.
n
a
m
e
i
n
t
o
@
t
e
s
t
a
l
l
2
f
r
o
m
u
s
e
r
u
w
h
e
r
e
u
.
i
d
=
2
;
E
N
D
CREATE PROCEDURE test_All2() BEGIN select u.name into @test_all2 from user u where u.id=2; END
CREATEPROCEDUREtestAll2()BEGINselectu.nameinto@testall2fromuseruwhereu.id=2;END
CALL test_All2()
S
E
L
E
C
T
@
t
e
s
t
a
l
l
2
SELECT @test_all2
SELECT@testall2
DELIMITER
C
R
E
A
T
E
P
R
O
C
E
D
U
R
E
t
e
s
t
l
o
o
p
(
)
B
E
G
I
N
d
e
c
l
a
r
e
n
u
m
i
n
t
d
e
f
a
u
l
t
0
;
m
y
l
o
o
p
:
l
o
o
p
s
e
l
e
c
t
n
u
m
;
i
f
n
u
m
>
9
t
h
e
n
l
e
a
v
e
m
y
l
o
o
p
;
e
n
d
i
f
;
s
e
t
n
u
m
=
n
u
m
+
1
;
e
n
d
l
o
o
p
m
y
l
o
o
p
;
E
N
D
CREATE PROCEDURE test_loop() BEGIN declare num int default 0; myloop:loop select num; if num>9 then leave myloop; end if; set num=num+1; end loop myloop; END
CREATEPROCEDUREtestloop()BEGINdeclarenumintdefault0;myloop:loopselectnum;ifnum>9thenleavemyloop;endif;setnum=num+1;endloopmyloop;END
CALL test_loop()$$/
/
loop 和 leave(相当于break) iterate(相当于continue) 搭配使用
repeat和 until 搭配使用
while 和do搭配使用
case语句和when then搭配使用,在begin end中需要加上case
cursor 游标,指定结果集,相当于(resttype),必须在局部变量声明后面
游标使用过程:声明 打开 获取数据 关闭
handle句柄声明,必须在游标声明后面
DELIMITER
C
R
E
A
T
E
P
R
O
C
E
D
U
R
E
t
e
s
t
i
t
e
r
a
t
e
(
)
B
E
G
I
N
d
e
c
l
a
r
e
n
u
m
i
n
t
d
e
f
a
u
l
t
0
;
D
E
C
L
A
R
E
s
t
r
v
a
r
c
h
a
r
(
256
)
D
E
F
A
U
L
T
′
0
′
;
m
y
l
o
o
p
:
l
o
o
p
s
e
t
n
u
m
=
n
u
m
+
1
;
s
e
t
s
t
r
=
c
o
n
c
a
t
(
s
t
r
,
′
,
′
,
n
u
m
)
;
i
f
n
u
m
<
10
t
h
e
n
i
t
e
r
a
t
e
m
y
l
o
o
p
;
e
n
d
i
f
;
l
e
a
v
e
m
y
l
o
o
p
;
e
n
d
l
o
o
p
m
y
l
o
o
p
;
s
e
l
e
c
t
s
t
r
;
E
N
D
CREATE PROCEDURE test_iterate() BEGIN declare num int default 0; DECLARE str varchar(256) DEFAULT '0'; myloop:loop set num=num+1; set str=concat(str,',',num); if num<10 then iterate myloop; end if; leave myloop; end loop myloop; select str; END
CREATEPROCEDUREtestiterate()BEGINdeclarenumintdefault0;DECLAREstrvarchar(256)DEFAULT′0′;myloop:loopsetnum=num+1;setstr=concat(str,′,′,num);ifnum<10theniteratemyloop;endif;leavemyloop;endloopmyloop;selectstr;END
CALL test_iterate()
∗
/
D
E
L
I
M
I
T
E
R
*/ DELIMITER
∗/DELIMITER
SELECT bookCounts,#在查询中使用
CASE bookCounts
WHEN 3 THEN ‘书的数量较少’
WHEN 20 THEN ‘书的数量充足’
ELSE ‘其它’
END
FROM book
#在存储函数中使用
DELIMITER $$
CREATE PROCEDURE test_case(IN num INT)
BEGIN
CASE num
WHEN 3 THEN SELECT'书的数量较少';
WHEN 20 THEN SELECT'书的数量充足';
ELSE SELECT '其它';
END CASE;
ENDKaTeX parse error: Expected 'EOF', got '#' at position 22: …test_case(20); #̲case的第二种用法,类似于多…
CREATE PROCEDURE test_case1(IN num INT)
BEGIN
CASE
WHEN num<5 THEN SELECT’书的数量较少’;
WHEN num BETWEEN 5 AND 19 THEN SELECT’书的数量适中’;
WHEN num>19 THEN SELECT’书的数量充足’;
ELSE SELECT’其它’;
END CASE;
END$$
CALL test_case1(10);
#**
游标篇
**
DELIMITER
C
R
E
A
T
E
P
R
O
C
E
D
U
R
E
c
u
r
s
o
r
t
e
s
t
(
)
B
E
G
I
N
D
E
C
L
A
R
E
n
u
m
I
N
T
D
E
F
A
U
L
T
0
;
D
E
C
L
A
R
E
r
I
N
T
D
E
F
A
U
L
T
0
;
D
E
C
L
A
R
E
m
y
c
u
r
s
o
r
C
U
R
S
O
R
F
O
R
S
E
L
E
C
T
b
o
o
k
C
o
u
n
t
s
F
R
O
M
b
o
o
k
;
O
P
E
N
m
y
c
u
r
s
o
r
;
R
E
P
E
A
T
S
E
T
r
=
r
+
1
;
F
E
T
C
H
m
y
c
u
r
s
o
r
I
N
T
O
n
u
m
;
S
E
L
E
C
T
n
u
m
;
U
N
T
I
L
r
>
2
E
N
D
R
E
P
E
A
T
;
C
L
O
S
E
m
y
c
u
r
s
o
r
;
E
N
D
CREATE PROCEDURE cursor_test() BEGIN DECLARE num INT DEFAULT 0; DECLARE r INT DEFAULT 0; DECLARE mycursor CURSOR FOR SELECT bookCounts FROM book; OPEN mycursor; REPEAT SET r=r+1; FETCH mycursor INTO num; SELECT num; UNTIL r>2 END REPEAT; CLOSE mycursor; END
CREATEPROCEDUREcursortest()BEGINDECLAREnumINTDEFAULT0;DECLARErINTDEFAULT0;DECLAREmycursorCURSORFORSELECTbookCountsFROMbook;OPENmycursor;REPEATSETr=r+1;FETCHmycursorINTOnum;SELECTnum;UNTILr>2ENDREPEAT;CLOSEmycursor;END
CALL cursor_test()
/*
delimiter
c
r
e
a
t
e
p
r
o
c
e
d
u
r
e
t
e
s
t
d
o
(
)
b
e
g
i
n
d
e
c
l
a
r
e
n
u
m
i
n
t
d
e
f
a
u
l
t
0
;
d
e
c
l
a
r
e
s
t
r
v
a
r
c
h
a
r
(
256
)
d
e
f
a
u
l
t
′
0
′
;
w
h
i
l
e
n
u
m
<
10
d
o
s
e
t
n
u
m
=
n
u
m
+
1
;
s
e
t
s
t
r
=
c
o
n
c
a
t
(
s
t
r
,
′
,
′
,
n
u
m
)
;
e
n
d
w
h
i
l
e
;
s
e
l
e
c
t
s
t
r
;
e
n
d
create procedure test_do() begin declare num int default 0; declare str varchar(256) default '0'; while num<10 do set num=num+1; set str=concat(str,',',num); end while; select str; end
createproceduretestdo()begindeclarenumintdefault0;declarestrvarchar(256)default′0′;whilenum<10dosetnum=num+1;setstr=concat(str,′,′,num);endwhile;selectstr;end
call test_do()
∗
/
/
∗
d
e
l
i
m
i
t
e
r
*/ /* delimiter
∗//∗delimiter
create procedure show_book()
begin
declare b_name varchar(100);
declare b_count int(11);
declare b_flag boolean default true;
declare b_cursor cursor for
select bookName,bookCounts from book;
DECLARE CONTINUE HANDLER FOR 1329 SET b_flag=FALSE;创建handler 句柄,必须声明在游标后面,当错误码为1329时,将b_flag设置为false然后继续执行
open b_cursor;
myloop:loop
fetch b_cursor into b_name,b_count;
if b_flag then
select b_name,b_count;
else
leave myloop;
end if;
end Loop myloop;
close b_cursor;
end
c
a
l
l
s
h
o
w
b
o
o
k
(
)
call show_book()
callshowbook()/
/ 创建下个月每天的表*/
/*select Last_day(Date_add(now(),interval 1 month));
select Year(LAST_DAY(DATE_ADD(NOW(),INTERVAL 1 MONTH)));
SELECT month(LAST_DAY(DATE_ADD(NOW(),INTERVAL 1 MONTH)));
SELECT dayofmonth(LAST_DAY(DATE_ADD(NOW(),INTERVAL 1 MONTH)));
delimiter KaTeX parse error: Expected group after '_' at position 767: …cat(year_next,'_̲',month_str,'_'…
delimiter
c
r
e
a
t
e
p
r
o
c
e
d
u
r
e
i
n
s
e
r
t
t
e
s
t
(
i
n
@
b
o
o
k
N
a
m
e
V
A
R
C
H
A
R
(
100
)
,
i
n
@
b
o
o
k
C
o
u
n
t
s
I
N
T
(
11
)
,
i
n
@
d
e
t
a
i
l
V
A
R
C
H
A
R
(
200
)
)
b
e
g
i
n
i
n
s
e
r
t
i
n
t
o
b
o
o
k
(
b
o
o
k
N
a
m
e
,
b
o
o
k
C
o
u
n
t
s
,
d
e
t
a
i
l
)
v
a
l
u
e
s
(
@
b
o
o
k
N
a
m
e
,
@
b
o
o
k
C
o
u
n
t
s
,
@
d
e
t
a
i
l
)
;
e
n
d
create procedure insert_test(in @bookName VARCHAR(100),in @bookCounts INT(11),in @detail VARCHAR(200)) begin insert into book(bookName,bookCounts,detail) values(@bookName,@bookCounts,@detail); end
createprocedureinserttest(in@bookNameVARCHAR(100),in@bookCountsINT(11),in@detailVARCHAR(200))begininsertintobook(bookName,bookCounts,detail)values(@bookName,@bookCounts,@detail);end
*/
#--------------------
视图篇
CREATE VIEW myview
AS SELECT * FROM book;
SELECT FROM myview;
#试图张可添加非表结构中的字段,如下
CREATE VIEW myview1
AS SELECT ,‘12345’ FROM book
SELECT * FROM myview1
#可根据聚合统计的sql创建试图
CREATE VIEW myview2
AS SELECT bookID,bookName,SUM(bookCounts) FROM book GROUP BY bookID,bookName;
SELECT * FROM myview2
#创建多表查询的试图,注意视图的字段民不要重复
CREATE VIEW myview3
AS SELECT b.,c. FROM book b RIGHT JOIN classification c ON b.bookID=c.id
SELECT * FROM myview3
CREATE VIEW myview4
AS SELECT b.bookID,c.id FROM book b ,classification c
SELECT * FROM myview4
#基于视图创建视图
CREATE VIEW view_test AS
SELECT * FROM myview2
SELECT * FROM view_test
SHOW TABLES
DESC myview#查看视图结构
SHOW TABLE STATUS LIKE ‘myview’#查看视图信息(存储引擎,版本,数据行等)
SHOW CREATE VIEW myview#查看视图详细定义信息
#视图的修改
CREATE OR REPLACE VIEW myview2
AS SELECT *FROM book WHERE bookID=1
ALTER VIEW myview2
AS SELECT *FROM book WHERE bookID=2
#删除视图
DROP VIEW IF EXISTS myview2
/*
存储函数篇
*/
DELIMITER C R E A T E F U N C T I O N t e s t 1 ( ) R E T U R N S V A R C H A R ( 30 ) B E G I N R E T U R N ( S E L E C T b o o k N a m e F R O M b o o k W H E R E b o o k I D = 1 ) ; E N D CREATE FUNCTION test_1() RETURNS VARCHAR(30) BEGIN RETURN(SELECT bookName FROM book WHERE bookID=1); END CREATEFUNCTIONtest1()RETURNSVARCHAR(30)BEGINRETURN(SELECTbookNameFROMbookWHEREbookID=1);END
SELECT test_1()
DELIMITER
C
R
E
A
T
E
F
U
N
C
T
I
O
N
t
e
s
t
2
(
I
D
I
N
T
)
R
E
T
U
R
N
S
V
A
R
C
H
A
R
(
30
)
B
E
G
I
N
R
E
T
U
R
N
(
S
E
L
E
C
T
b
o
o
k
N
a
m
e
F
R
O
M
b
o
o
k
W
H
E
R
E
b
o
o
k
I
D
=
I
D
)
;
E
N
D
CREATE FUNCTION test_2(ID INT) RETURNS VARCHAR(30) BEGIN RETURN(SELECT bookName FROM book WHERE bookID=ID); END
CREATEFUNCTIONtest2(IDINT)RETURNSVARCHAR(30)BEGINRETURN(SELECTbookNameFROMbookWHEREbookID=ID);END
SELECT test_2(1)
DROP FUNCTION test_2
DELIMITER
C
R
E
A
T
E
F
U
N
C
T
I
O
N
t
e
s
t
3
(
)
R
E
T
U
R
N
S
I
N
T
B
E
G
I
N
R
E
T
U
R
N
(
S
E
L
E
C
T
S
U
M
(
b
o
o
k
C
o
u
n
t
s
)
F
R
O
M
b
o
o
k
)
;
E
N
D
CREATE FUNCTION test_3() RETURNS INT BEGIN RETURN(SELECT SUM(bookCounts) FROM book); END
CREATEFUNCTIONtest3()RETURNSINTBEGINRETURN(SELECTSUM(bookCounts)FROMbook);END
SELECT test_3()
SHOW PROCEDURE STATUS LIKE’test_%';
SHOW FUNCTION STATUS LIKE ‘test_%’;
/*
触发器篇
*/
DELIMITER KaTeX parse error: Expected 'EOF', got '#' at position 26: …IGGER mytrigger#̲创建触发器 AFTER INS…
INSERT INTO book(bookName,bookCounts,detail) VALUES(‘c#’,10,‘这个真垃圾’);
SELECT *FROM book
SELECT *FROM classification WHERE cname=‘书本’
#查看所有触发器
SHOW TRIGGERS
#查看自定义触发器
SHOW CREATE TRIGGER mytrigger
DROP TRIGGER IF EXISTS mytrigger
/*异常处理篇,类似于句柄,上面用过,
continue :遇到错误不处理继续执行
exit:遇到错误退出
undo:遇到错误撤回之前的操作,mysql中暂不支持这种操作
*/
DECLARE EXIT HANDLER FOR myerro SET @info=‘该值不存在’;
SELECT @info
SELECT *FROM book WHERE bookID=;
DELIMITER $$
CREATE PROCEDURE test_condition()
BEGIN
#DECLARE myerro CONDITION FOR 1054;#为1054错误码定义异常名myerro,方便处理
DECLARE EXIT HANDLER FOR 1054 SET @info=‘没有该列’;
UPDATE book SET books=1 WHERE bookID=1;
SELECT @info;
END$$
CALL test_condition()
SELECT @info
事务篇
#查看事务状态,mysql中事务默认为自动提交,回滚是在事务提交前回滚的,
#故使用回滚和提交时,先将自动提交改为手动提交
SHOW VARIABLES LIKE ‘%autocommit%’
#将事务设置为手动,1的话代表自动提交
SET autocommit=1;
SELECT* FROM book
UPDATE book SET bookCounts=bookCounts+20 WHERE bookID=1;
UPDATE book SET bookCounts=bookCounts-10 WHERE bookID=1;
UPDATE book SET bookCounts=bookCounts-10 WHERE bookID=1;
ROLLBACK