Mysql学习笔记(十)存储过程与函数 + 知识点补充(having与where的区别)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 原文:Mysql学习笔记(十)存储过程与函数 + 知识点补充(having与where的区别)学习内容:存储程序与函数。。。这一章学的我是云里雾里的。。。 1.存储过程。。。   Mysql存储过程是从mysql 5.0开始增加的一个新功能.存储过程的优点其实有很多,不过我觉得存储过程最重要的优点就是实现了SQL代码的封装,那么我们为什么需要封装SQL语句呢?原因就是当我们在面对一个庞大的数据库的时候,当我们使用外部程序去访问数据库的时候。
原文: Mysql学习笔记(十)存储过程与函数 + 知识点补充(having与where的区别)

学习内容:
存储程序与函数。。。这一章学的我是云里雾里的。。。

1.存储过程。。。

  Mysql存储过程是从mysql 5.0开始增加的一个新功能.存储过程的优点其实有很多,不过我觉得存储过程最重要的优点就是实现了SQL代码的封装,那么我们为什么需要封装SQL语句呢?原因就是当我们在面对一个庞大的数据库的时候,当我们使用外部程序去访问数据库的时候。。。我们总不能在外部程序中内嵌很多的SQL语句吧。。。那样执行的效率不高,并且也不容易维护...因此存储过程将我们的操作进行封装,当我们需要对其进行操作的时候,我们只需要调用存储过程就可以了...

create procedure cl_add
(
    a int,
    b int
)
begin                 //存储过程的执行过程需要定义在begin。。。。end语句中...
  declare c int;      //声明一个变量。。declare只能使用在存储过程或者函数里面,否则会出错..
  if a is null then   //if 语句 ,用来进行条件判断。。满足条件则执行满足条件的语句..这里的if和if()是不同的。。if()是控制流程函数。。if表示条件判断的语句...二者是不一样的..
     set a=0;
  end if;
  if b is null then
     set b=0;         //set 赋值语句...可以接简单的语句还可以接复杂的函数...
  end if;
  set c=a+b;
  select c as sum;
  /* 
   return c; 这会产生错误...
  */
end;

注:存储过程中不能使用return...return只能使用在函数中...

存储过程的调用...

call cl_add(10,20); //存储过程需要使用call函数来进行调用...

set @a=10; set @b=20; //我们还可以定义两个用户变量...

call cl_add(@a,@b); //将用户变量的值传递过去...

2.存储函数。。。

 

存储函数也是由一个或多个SQL语句组成的,目的是将代码封装以便重新使用...也是为了方便开发人员操作数据库...

 

存 储函数使用的限制:1.不能使用临时表。2.不能在存储函数中定义timestamp,cursor,table的数据类型...3.定义函数时参数只允 许是in类型...4.系统内置了一些存储函数,在调用这些函数的时候...需要加::前缀...并启用allow updates服务器选项,才能将用户自定义的函数的所有者定义为系统类型..

 

 

DELIMITER //

CREATE FUNCTION NameByT()
RETURNS CHAR(50)
RETURN (SELECT NAME FROM t3 WHERE id=2);
//
DELIMITER ;

 

创建存储函数,名称为NameByT,该函数返回SELECT语句的查询结果,数值类型为字符串型...

注意:RETURNS CHAR(50)数据类型的时候,RETURNS 是有S的,而RETURN (SELECT NAME FROM t3 WHERE id=2)的时候RETURN是没有S的

 

3.存储函数和存储过程的区别...

本质上都是实现SQL代码块的封装,方便对数据库的操作...

存储过程和函数存在以下几个区别:

    1)一般来说,存储过程实现的功能要复杂一点,而函数的实现的功能针对性比较强。存储过程,功能强大,可以执行包括修改表等一系列数据库操作;用户定义函数不能用于执行一组修改全局数据库状态的操作。
    2)对于存储过程来说可以返回参数,如记录集,而函数只能返回值或者表对象。函数只能返回一个变量;而存储过程可以返回多个。存储过程的参数可以有 IN,OUT,INOUT三种类型,而函数只能有IN类~~存储过程声明时不需要返回类型,而函数声明时需要描述返回类型,且函数体中必须包含一个有效的 RETURN语句。
    3)存储过程,可以使用非确定函数,不允许在用户定义函数主体中内置非确定函数。
    4)存储过程一般是作为一个独立的部分来执行( EXECUTE 语句执行),而函数可以作为查询语句的一个部分来调用(SELECT调用),由于函数可以返回一个表对象,因此它可以在查询语句中位于FROM关键字的后 面。 SQL语句中不可用存储过程,而可以使用函数。
总结:

  用户自定义函数在处理同一数据行中的各个字段时,特别方便有用。虽然这里使用存储过程也能达到查询目的,但是显然没有使用函数方便。而且,即使使用存储过程也无法处理SELECT查询中的同一数据行中的各个字段的运算。因为存储过程不返回值(唯一可以直接返回整型值,虽然没有返回值,但是可以在存储过程中输出参数来完成返回),使用时只能单独调用;而函数却能出现在能放置表达式的任何位置。

4.Mysql也可以使用declare定义条件和存储程序来解决一些问题...这里所说的问题一般就是错误,当我们在处理一些错误的时候,我们可以自定义一个程序来处理错误....

CREATE TABLE t8(s1 INT,PRIMARY KEY(s1))

DELIMITER //
CREATE PROCEDURE handlerdemo()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @X2=1;
SET @X=1;
INSERT INTO t8 VALUES(1);
SET @X=2;
INSERT INTO t8 VALUES(1);
SET @X=3;
END;
//
DELIMITER ;

/* 调用存储过程*/
CALL handlerdemo();

/* 查看调用存储过程结果*/
SELECT @X

  这里我们插入了两次1。。这在主键里是不允许出现的....因此我们使用了DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @X2=1;这个语句来处理这个错误发生...如果没有这句话。。这段代码就是错误的....

5.知识点有所遗漏,也是今天偶尔发现自己不会的一个知识点。。。

数据库查询语句中的having与where的区别。。。

一个很小的知识点。。。不过比较重要。。。

  一般在sql中,大多数情况下都是使用where,而很少使用having,where和having基本差不多,having子句在查询过程中慢于聚合语句,where子句在查询过程中快与查询语句,因此大多数的情况下都是使用where的。。。

SELECT * FROM `welcome` HAVING id >1 LIMIT 0 , 30
SELECT * FROM `welcome` WHERE id >1 LIMIT 0 , 30

//这两种运行结果是一样的。。。在多数情况下能使用where的时候就尽量不要使用having,。因为where要快于聚合语句。。。having的使用是要弥补where在分组数据判断时的不足。。。比如说下面代码。。。。
SELECT user, MAX(salary) FROM users GROUP BY user HAVING MAX(salary)>10;
SELECT user, MAX(salary) FROM users GROUP BY user WHERE MAX(salary)>10;
第二种语句就会出现错误,在数据库中where的后面是不允许加带判断性的聚合函数的。。因此如果当我们统计数据的时候使用到了聚合语句...我们就只能使用having了。。如果不用这些关系,那么当然where是首选。。。

再补充几点:

1、SQL标准要求HAVING必须引用GROUP BY子句中的列或用于总计函数中的列。不过,MySQL支持对此工作性质的扩展,并允许HAVING涉及SELECT清单中的列和外部子查询中的列。

2、HAVING子句必须位于GROUP BY之后ORDER BY之前。

3、如果HAVING子句引用了一个意义不明确的列,则会出现警告。在下面的语句中,col2意义不明确,因为它既作为别名使用,又作为列名使 用:mysql> SELECT COUNT(col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2;

标准SQL工作性质具有优先权,因此如果一个HAVING列名既被用于GROUP BY,又被用作输出列清单中的起了别名的列,则优先权被给予GROUP BY列中的列。

4、HAVING子句可以引用总计函数,而WHERE子句不能引用。【这应该是开发者在特定的情况下采用HAVING子句的最大原因】

5、不要将HAVING用于应被用于WHERE子句的条目,从我们开头的2条语句来看,这样用并没有出错,但是mysql不推荐。而且也没有明确说明原因,但是既然它要求,我们遵循就可以了。

 

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
20天前
|
存储 SQL 关系型数据库
mysql 的ReLog和BinLog区别
MySQL中的重做日志和二进制日志是确保数据库稳定性和可靠性的关键组件。重做日志主要用于事务的持久性和原子性,通过记录数据页的物理修改信息来恢复未提交的事务;而二进制日志记录SQL语句的逻辑变化,支持数据复制、恢复和审计。两者在写入时机、存储方式及配置参数等方面存在显著差异。
|
2月前
|
存储 SQL 关系型数据库
Mysql学习笔记(二):数据库命令行代码总结
这篇文章是关于MySQL数据库命令行操作的总结,包括登录、退出、查看时间与版本、数据库和数据表的基本操作(如创建、删除、查看)、数据的增删改查等。它还涉及了如何通过SQL语句进行条件查询、模糊查询、范围查询和限制查询,以及如何进行表结构的修改。这些内容对于初学者来说非常实用,是学习MySQL数据库管理的基础。
141 6
|
1天前
|
存储 缓存 关系型数据库
【MySQL进阶篇】存储引擎(MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案)
MySQL的存储引擎是其核心组件之一,负责数据的存储、索引和检索。不同的存储引擎具有不同的功能和特性,可以根据业务需求 选择合适的引擎。本文详细介绍了MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案。
【MySQL进阶篇】存储引擎(MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案)
|
22天前
|
存储 关系型数据库 MySQL
MySQL引擎InnoDB和MyISAM的区别?
InnoDB是MySQL默认的事务型存储引擎,支持事务、行级锁、MVCC、在线热备份等特性,主索引为聚簇索引,适用于高并发、高可靠性的场景。MyISAM设计简单,支持压缩表、空间索引,但不支持事务和行级锁,适合读多写少、不要求事务的场景。
51 9
|
1月前
|
存储 NoSQL 关系型数据库
MySQL和Redis的区别
**MySQL和Redis的区别** MySQL和Redis都是流行的数据存储解决方案,但它们在设计、用途和特性上有显著区别。理解这些区别有助于选择合适的数据库来满足不同的应用需求。本文将详细介绍MySQL和Redis的区别,包括它们的架构、使用场景、性能和其他关键特性。 ### 一、基本概述 **MySQL**: MySQL是一个关系型数据库管理系统(RDBMS),使用结构化查询语言(SQL)进行数据管理。它支持事务、复杂查询和多种存储引擎,广泛应用于各种Web应用、企业系统和数据分析项目。 **Redis**: Redis是一个基于内存的键值数据库,通常被称为NoSQL数
87 4
|
1月前
|
存储 SQL 关系型数据库
mysql 的ReLog和BinLog区别
MySQL中的重做日志(Redo Log)和二进制日志(Binary Log)是两种重要的日志系统。重做日志主要用于保证事务的持久性和原子性,通过记录数据页的物理修改信息来恢复未提交的事务更改。二进制日志则记录了数据库的所有逻辑变化操作,用于数据的复制、恢复和审计。两者在写入时机、存储方式、配置参数和使用范围上有所不同,共同确保了数据库的稳定性和可靠性。
|
2月前
|
SQL 关系型数据库 MySQL
Mysql学习笔记(三):fetchone(), fetchmany(), fetchall()详细总结
MySQL中用于数据检索的`fetchone()`, `fetchmany()`, `fetchall()`函数的功能、SQL语句示例和应用场景。
85 3
Mysql学习笔记(三):fetchone(), fetchmany(), fetchall()详细总结
|
2月前
|
SQL Ubuntu 关系型数据库
Mysql学习笔记(一):数据库详细介绍以及Navicat简单使用
本文为MySQL学习笔记,介绍了数据库的基本概念,包括行、列、主键等,并解释了C/S和B/S架构以及SQL语言的分类。接着,指导如何在Windows和Ubuntu系统上安装MySQL,并提供了启动、停止和重启服务的命令。文章还涵盖了Navicat的使用,包括安装、登录和新建表格等步骤。最后,介绍了MySQL中的数据类型和字段约束,如主键、外键、非空和唯一等。
79 3
Mysql学习笔记(一):数据库详细介绍以及Navicat简单使用
|
1月前
|
存储 SQL NoSQL
|
2月前
|
关系型数据库 MySQL 数据库
Mysql学习笔记(四):Python与Mysql交互--实现增删改查
如何使用Python与MySQL数据库进行交互,实现增删改查等基本操作的教程。
73 1