MySQL数据库编程02

Posted Weikun Xing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL数据库编程02相关的知识,希望对你有一定的参考价值。

文章目录

程序控制流语句

语句块、注释和重置命令结束标记

语句块

BEGIN…END用于定义SQL语句块

BEGIN
	SQL语句|SQL语句块
END

BEGIN…END语句块包含了该程序块的所有处理操作,允许语句块嵌套
mysql中单独使用BEGIN…END语句块没有任何意义,只有将其封装到存储过程、存储函数、触发器等存储程序内部才有意义。

注释

单行注释

mysql> show databases; #列出所有数据库
+--------------------+
| Database           |
+--------------------+
| daxuepaiming       |
| guanli             |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

多行注释

mysql> /*
   /*> 多行注释
   /*> 使用数据库*/
mysql> use daxuepaiming;
Database changed

重置命令结束标记

在MySQL中,服务器处理的语句是以分号为结束标记的。但在创建存储函数、存储过程的时候,在函数体或存储过程体中可以包含多个SQL语句,每个SQL语句都是以分号结尾,而服务器处理程序时遇到第1个分号则结束程序的执行,这时就需要使用DELIMITER语句将MySQL语句的结束标记修改为其他符号。
符号可以是一些特殊符号,如两个#两个@两个$两个%等,避免使用/因为它是MySQL的转义字符

mysql> DELIMITER @@
mysql> SHOW TABLES@@
+------------------------+
| Tables_in_daxuepaiming |
+------------------------+
| dxpm                   |
+------------------------+

恢复使用分号作为结束标记

mysql> DELIMITER ;
mysql> SHOW TABLES;
+------------------------+
| Tables_in_daxuepaiming |
+------------------------+
| dxpm                   |
+------------------------+

存储函数

存储函数的创建

mysql> USE company;
Database changed
mysql> SHOW TABLES;
+-------------------+
| Tables_in_company |
+-------------------+
| dept              |
| emp               |
| salgrade          |
+-------------------+
3 rows in set (0.00 sec)

mysql> SELECT * FROM dept;
+--------+------------+----------+
| deptno | dname      | loc      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLS    |
|     30 | SALES      | CHICAGO  |
|     40 | OERATIONS  | BOSTON   |
+--------+------------+----------+

创建存储函数name_fn(),根据所给的部门编号值deptno,函数返回该部门的部门名称dname

DELIMITER @@
CREATE FUNCTION name_fn(dno DECIMAL(2))
    RETURNS VARCHAR(14)
    DETERMINISTIC
    BEGIN
		RETURN(SELECT dname FROM dept
			WHERE deptno=dno);
    END@@

调用存储函数

DELIMITER ;
SELECT name_fn(20);

删除存储函数

DROP FUNCTION name_fn;

条件判断语句

程序中变量的使用

局部变量可以在程序中声明并使用,这些变量的作用范围是BEGIN…END语句块。

声明变量

DECLARE:声明的局部变量,变量名前不能加@
DEFAULT:子句提供了一个默认值,如果没有给默认值,局部变量的初始值默认为NULL

为变量赋值

创建求任意两个数之和的存储函数sum_fn()

DELIMITER @@
CREATE FUNCTION sum_fn(a DECIMAL(5,2),b DECIMAL(5,2))
RETURNS DECIMAL
DETERMINISTIC
	BEGIN
		DECLARE x,y DECIMAL(5,2);
        SET x=a,y=b;
        RETURN x+y;
	END@@
DELIMITER ;
mysql> SELECT sum_fn(7,3);
+-------------+
| sum_fn(7,3) |
+-------------+
|          10 |
+-------------+

IF语句

判断整型变量a和b的大小

DELIMITER @@
CREATE FUNCTION max_fn(a int,b int)
RETURNS int
DETERMINISTIC
	BEGIN
		if a>b THEN
			return a;
		else 
			return b;
		end if;
	END@@
DELIMITER ;
SELECT concat('最大值为:',convert(max_fn(7,3),char(3))) 最大值;
+----------------+
| 最大值         |
+----------------+
| 最大值为:7     |
+----------------+

判断某一年是否为闰年(能被4整除但不能被100整除;或者能被400整除)
<>是不等号的意思

DELIMITER @@
CREATE FUNCTION leap_year(year_date int)
RETURNS varchar(20)
DETERMINISTIC
	BEGIN
		declare leap boolean;
		if mod(year_date,4)<>0 then
			set leap=false;
            elseif mod(year_date,100)<>0 then
				set leap=true;
			elseif mod(year_date,400)<>0 then
				set leap=false;
			else set leap=true;
            end if;
            if leap then
				return(concat(convert(year_date,char(4)),"年是闰年"));
			else
				return(concat(convert(year_date,char(4)),"年是平年"));
			end if;
	END@@
DELIMITER ;
SELECT leap_year(2012);
+------------------+
| leap_year(2012)  |
+------------------+
| 2012年是闰年     |
+------------------+

CASE语句

mysql> SELECT ename 姓名,CASE job
    -> WHEN 'SALESMAN' THEN '销售员'
    -> WHEN 'CLERK' THEN '管理员'
    -> ELSE '经理'
    -> END AS 职务
    -> FROM emp LIMIT 3;
+--------+-----------+
| 姓名   | 职务      |
+--------+-----------+
| SMITH  | 管理员    |
| ALLEN  | 销售员    |
| WARD   | 销售员    |
+--------+-----------+
mysql> SELECT ename,sal,CASE
    -> WHEN sal BETWEEN 700 AND 1200 THEN '一级'
    -> WHEN sal BETWEEN 1201 AND 1400 THEN '二级'
    -> WHEN sal BETWEEN 1401 AND 2000 THEN '三级'
    -> WHEN sal BETWEEN 2001 AND 3000 THEN '四级'
    -> ELSE '五级'
    -> END 工资等级
    -> FROM emp LIMIT 3;
+-------+---------+--------------+
| ename | sal     | 工资等级     |
+-------+---------+--------------+
| SMITH |  800.00 | 一级         |
| ALLEN | 1600.00 | 三级         |
| WARD  | 1250.00 | 二级         |
+-------+---------+--------------+

循环语句

LOOP循环

语法格式

标签:LOOP
	SQL语句块;
	IF <条件表达式> THEN
		LEAVE 标签;
	END IF;
END LOOP;

返回1~n的和

delimiter @@
create function sum_fn(n int)
returns int
DETERMINISTIC
begin
	declare s,i int;
    set s=0,i=1;
    loop_label:loop
		set s=s+i;
        set i=i+1;
        if i>n then
			leave loop_label;
		end if;
	end loop;
    return s;
end@@
delimiter ;
select sum_fn(100);

WHILE循环

语法格式

WHILE <条件表达式> DO
	SQL语句块;
END WHILE;
delimiter @@
create function sum_fn(n int)
returns int
DETERMINISTIC
begin
	declare s,i int;
    set s=0,i=1;
    while i<=n do
		set s=s+i;
        set i=i+1;
	end while;
    return s;
end@@
delimiter ;
select sum_fn(100);

REPEAT循环

REPEAT 
	SQL语句块;
	UNTIL <条件表达式>
END REPEAT;
delimiter @@
create function sum_fn(n int)
returns int
DETERMINISTIC
begin
	declare s,i int;
    set s=0,i=1;
    repeat
		set s=s+i;
        set i=i+1;
        until i>n
	end repeat;
    return s;
end@@
delimiter ;
select sum_fn(100);

存储过程

创建存储过程

delimiter @@
create procedure emp_p()
DETERMINISTIC
begin
	select ename,job from emp
		where empno=7369;
end@@

调用存储过程

delimiter ;
call emp_p();

存储过程的参数

IN参数

delimiter @@
create procedure dept_p1(
	in p_deptno decimal(2,0),
    in p_dname varchar(14),
    in p_loc varchar(13)
)
DETERMINISTIC
begin
	insert into dept
		values(p_deptno,p_dname,p_loc);
end@@
delimiter ;
call dept_p1(50,'HR','CHINA');
select * from dept where deptno=50;

OUT参数

delimiter @@
create procedure dept_p2(
	in i_no decimal(2,0),
    out o_name varchar(14),
    out o_loc varchar(13)
)
DETERMINISTIC
begin
	select dname,loc into o_name,o_loc from dept
		where deptno=i_no;
end@@
delimiter ;
call dept_p2(10,@v_dname,@v_loc);
select @v_dname,@v_loc;

INOUT参数

delimiter @@
create procedure swap(
	inout p_num1 int,
    inout p_num2 int
)
DETERMINISTIC
begin
	declare var_temp int;
    set var_temp=p_num1;
    set p_num1=p_num2;
    set p_num2=var_temp;
end@@
set @v_num1=1;
set @v_num2=2;
call swap(@v_num1,@v_num2);
select @v_num1,@v_num2;

删除存储过程

drop procedure emp_p;

游标

游标的定义和使用

创建存储过程emp_p,用游标提取emp表中的7788雇员的姓名和职务

delimiter @@
create procedure emp_p()
DETERMINISTIC
begin
	declare v_ename varchar(14);
    declare v_job varchar(13);
    declare emp_cursor cursor	#声明游标
    for select ename,job from emp
    where empno=7788;
    open emp_cursor;	#打开游标
    fetch emp_cursor into v_ename,v_job;	#提取游标数据到变量
    close emp_cursor;	#关闭游标
    select v_ename,v_job;
end@@
delimiter ;
call emp_p();

异常处理

delimiter @@
create function emp_ins_fun(no decimal(4,0),name varchar(14))
returns varchar(20)
DETERMINISTIC
begin
	declare exit handler for sqlstate '23000'
    return '违反主键约束';
    insert into emp(empno,ename) values(no,name);
    return '插入成功';
end@@
delimiter ;
select emp_ins_fun(7369,'MARY');

delimiter ;
select emp_ins_fun(7000,'MARY');

以上是关于MySQL数据库编程02的主要内容,如果未能解决你的问题,请参考以下文章

使用Java实现数据库编程—02 第二章 初始MySQL

MySQL实现类似Oracle序列的方案

MySQL数据库编程02

R语言统计(02)——合并不等数据矩阵

MySQL 分区修剪始终包括不等式查询中的第一个分区

公务员怎么查工资