在数据库操作中, 尤其是碰到一些复杂一些的系统, 不可避免的, 会用到函数/自定义函数, 或者存储过程.

实际项目中, 自定义函数和存储过程是越少越好, 因为这个东西多了, 也是一个非常难以维护的地方.

一、自定义函数

1. 例子

mysql提供的函数, 不在这一篇讲了, 这里主要贴一下自定义函数.  前台js插件里面有一个zTree, 不知道大家知不知道, 效果是这样的:

这种结构的数据, 在数据库中, 我一般会设计到一个表中

create table ztree
(
id int(11) not null PRIMARY key auto_increment,
name varchar(20) not null comment '节点名称',
pid int(11) not null comment '父节点id'
) comment '树形表';

然后插入数据:

如果你拿到一个节点A, 想要获取A下面的节点(不只是子节点哦), 那么通过一个自定义函数来做, 能方便许多.

delimiter $
DROP FUNCTIONIF EXISTS GetChildNodes ;
CREATE FUNCTION `GetChildNodes` (`rootId` INT) RETURNS VARCHAR (1000)
BEGIN
DECLARE res VARCHAR (1000) DEFAULT '-1';
DECLARE temp VARCHAR (1000) DEFAULT CAST(rootId AS CHAR);
-- SET res = '' ;
-- SET DECLARE = CAST(rootId AS CHAR) ;
WHILE temp IS NOT NULL DO SET res = CONCAT(res, ',', temp) ; SELECT GROUP_CONCAT(id) INTO temp FROM ztree WHERE FIND_IN_SET(pid, temp) > 0 ; END WHILE ;
RETURN res ;
END$
delimiter ;

这里, 我将res的值默认为-1, 这样的话, 就可以在查询的时候, 将这个结果拼入sql中, 还是比较方便的.

mysql中, 自定义函数的调用, 使用 select, 接下来, 就看一下之前的成果:

SELECT GetChildNodes (2);

2. 语法

自定义函数与存储过程有一个很明显的地方, 就是, 自定义函数是有返回值的, 并且需要通过return的方式返回. 而存储过程没有return返回值. 但是, 程序在执行存储过程的时候, 其实是可以得到一个结果集的.

语法:

  create function 函数名 (参数名 参数类型) returns 参数类型

  begin

  return result;

  end

1) 自定义函数传参与存储过程不同, 不需要指定 in/out.

2) 自定义函数可以用到别的sql语句中, 可以单独使用, 也可以混入别的sql中使用

二、存储过程

既然前面已经讲了自定义函数的语法, 那这里就先上存储过程的语法, 以便比较

1. 语法

  CREATE PROCEDURE 存储过程名称 (IN 参数名 参数类型, OUT 参数名 参数类型)

  begin

  end

这里的参数都是非必须的, 可以有 IN/OUT 都是可以没有的

从语法格式上看, 与自定义函数的框架大致是一样的, 只是其中的细节不同.

1) 存储过程没有return返回值, 但是却可以通过OUT的方式, 来修改传入的参数, 可以当做是一种返回值,

2) 存储过程在end之前, 可以加上一句 select语句, 以便程序读取到结果集. 所以存储过程能返回的值其实更多

3) 并不能混入别的sql中使用, 只能通过 call 的方式, 单独使用

2. 例子

之前的项目中, 我碰到一个生成流水号的功能. 当时, 我是通过借助数据库的方式, 来生成流水号的.

我这里的流水号, 由前缀, 时间, 流水码 三部分组成

先建一张流水号表

CREATE TABLE `serialno` (
`Id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Id',
`Pre` varchar(10) NOT NULL COMMENT '编号',
`Description` varchar(10) DEFAULT NULL COMMENT '说明',
`Res` varchar(20) DEFAULT NULL COMMENT '流水号(不加编号的)',
PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='流水号表'

有了这张表, 就可以开始存储过程了.

delimiter $
drop PROCEDURE if EXISTS p_GetSerialNo;
CREATE PROCEDURE `p_GetSerialNo`(IN preValue VARCHAR(10), IN preDate VARCHAR(10),IN des varchar(20), in length int)
BEGIN
DECLARE t_error INT DEFAULT 0;
DECLARE resValue VARCHAR(20) DEFAULT NULL;
-- DECLARE
-- CONTINUE HANDLER FOR SQLEXCEPTION,
-- SQLWARNING,
-- NOT FOUND
-- SET t_error = 1; START TRANSACTION; SELECT Res INTO resValue FROM serialno WHERE Pre=preValue;
IF resValue IS NULL THEN
SET resValue= CONCAT(preDate, LPAD(1, length, ''));
INSERT INTO serialno (Pre, Description, Res) VALUES (preValue, des, resValue);
ELSE
IF preDate = (SUBSTRING(resValue,1,8) + '') THEN
SET resValue = CAST(resValue AS SIGNED) + 1;
if preDate <> SUBSTRING(resValue,1,8) THEN
set t_error = -1;
end if;
ELSE
SET resValue= CONCAT(preDate, LPAD(1, length, ''));
END IF;
UPDATE serialno SET Res = resValue WHERE Pre = preValue;
END IF; #IF t_error = 1 then
IF @@error_count <> 0 | t_error <> 0 THEN
ROLLBACK;
select t_error;
ELSE
COMMIT;
SELECT CONCAT(preValue, resValue);
END IF;
END $
delimiter ;

这里的参数preValue为前缀, preDate为8位的日期,格式如:"20161227", 参数des为说明, 此处并不参与逻辑, 只是更新一个字段. 最后一个length字段, 表示流水号的位数. 流水号的位数不能设置的太过小, 得视业务来确定. 当流水号溢出时, 会返回-1.

OK, 来看一下效果:

call p_GetSerialNo( 'b', '',  'b', 4);

Mysql - 存储过程/自定义函数的更多相关文章

  1. mysql创建自定义函数与存储过程

    mysql创建自定义函数与存储过程 一 创建自定义函数 在使用mysql的过程中,mysql自带的函数可能不能完成我们的业务需求,这时就需要自定义函数,例如笔者在开发过程中遇到下面这个问题 mysql ...

  2. MYSQL存储过程和函数学习笔记

    学至Tarena金牌讲师,金色晨曦科技公司技术总监沙利穆课程笔记的综合. 1. 什么是存储过程和函数 将SQL语句放入一个集合里,然后直接调用存储过程和函数来执行已经定义好的SQL语句,通过存储过程和 ...

  3. Paip.断点调试MYSQL存储过程跟函数的解决方案大法

    Paip.断点调试MYSQL存储过程跟函数的解决方案大法 作者Attilax ,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址:http://blog.csdn ...

  4. Mysql存储过程和函数

    Mysql存储过程和函数 基本概念: 创建存储过程和函数是指将经常使用的一组SQL语句的组合在一起,并将这些SQL语句当作一个整体存储在MySQL服务器中.例如,银行经常需要计算用户的利息.不同类别的 ...

  5. navicat与phpmyadmin做mysql的自定义函数和事件

    自定义函数和事件是mysql一个很方便的功能,navicat在5.1以上版本就支持了自定义函数和事件,phpmyadmim不清楚. 用这个是由于一些简单的事情,没有必要去做一个服务器计划使用 接下来我 ...

  6. MySql存储过程与函数详解

    存储过程和函数是在数据库中定义一些SQL语句的集合,然后直接调用这些存储过程和函数来执行已经定义好的SQL语句.存储过程和函数可以避免开发人员重复的编写相同的SQL语句.而且,存储过程和函数是在MyS ...

  7. MYSql 存储过程自定义跳出

    MYSql存储过程自定义跳出 我们有时会在存储过程中进行一些判断,当判断条件达成时候我们有时会直接跳出存储过程. 但是存储过程不支持return直接返回的操作, 所以我们只能采用另一种方法,'leav ...

  8. 12.Mysql存储过程和函数

    12.存储过程和函数12.1 什么是存储过程和函数存储过程和函数是事先经过编译并存储在数据库中的一段SQL语句的集合,调用存储过程和函数简化应用开发人员的工作,减少数据在数据库和应用服务器之间的传输, ...

  9. mysql 存储过程,函数,触发器

    存储过程和函数 mysql> HELP CREATE PROCEDURE; Name: 'CREATE PROCEDURE' Description: Syntax: CREATE [DEFIN ...

随机推荐

  1. Python 爬虫模拟登陆知乎

    在之前写过一篇使用python爬虫爬取电影天堂资源的博客,重点是如何解析页面和提高爬虫的效率.由于电影天堂上的资源获取权限是所有人都一样的,所以不需要进行登录验证操作,写完那篇文章后又花了些时间研究了 ...

  2. Docker 第一篇--初识docker

    已经多年不写博客, 看完<晓松奇谈>最后一期猛然觉醒, 决定仔细梳理下自己这几年的知识脉络. 既然决定写, 那么首先就从最近2年热门的开源项目Docker开始.Docker 这两年在国内很 ...

  3. 学习ASP.NET Core,怎能不了解请求处理管道[1]: 中间件究竟是个什么东西?

    ASP.NET Core管道虽然在结构组成上显得非常简单,但是在具体实现上却涉及到太多的对象,所以我们在 "通过重建Hosting系统理解HTTP请求在ASP.NET Core管道中的处理流 ...

  4. 【开源】.Net Api开放接口文档网站

    开源地址:http://git.oschina.net/chejiangyi/ApiView 开源QQ群: .net 开源基础服务  238543768 ApiView .net api的接口文档查看 ...

  5. C#中将DataTable导出为HTML的方法

    今天我要向大家分享一种将DataTable导出为到HTML格式的方法.有时我们需要HTML格式的输出数据, 以下代码就可以帮助我们达到目的,. 首先,我们要绑定DataTable和 DataGridV ...

  6. 获取 dhcp IP 过程分析 - 每天5分钟玩转 OpenStack(91)

    前面我们已经讨论了 DHCP agent 的配置以及 namespace 如何隔离 dnsmasq 服务,本节将以 cirros-vm1 为例分析获取 DHCP IP 的详细过程. 在创建 insta ...

  7. 文件随机读写专用类——RandomAccessFile

     RandomAccessFile类可以随机读取文件,但是在测试中并不好用;File类可以测试文件存不存在,不存在可以创建文件;FileWriter类可以对文件进行重写或者追加内容;FileReade ...

  8. 初识的Spring Mvc-----原理

    一.Spring Mvc简介 Spring Mvc(Spring Web Mvc) 属于表现层的框架. 二.Spring结构图 Spring Mvc是Spring框架里面web模块的一部分,是在Spr ...

  9. 如何理解javaSript中函数的参数是按值传递

    本文是我基于红宝书<Javascript高级程序设计>中的第四章,4.1.3传递参数小节P70,进一步理解javaSript中函数的参数,当传递的参数是对象时的传递方式. (结合资料的个人 ...

  10. Linux学习笔记(一):常用命令

    经过统计Linux中能够识别的命令超过3000种,当然常用的命令就远远没有这么多了,按照我的习惯,我把已经学过的Linux常用命令做了以下几个方面的分割: 1.文件处理命令 2.文件搜索命令 3.帮助 ...