MySQL - 存储过程

一、概述

  存储过程可以理解为一段 SQL 语句的集合(相当于 PHP 中的一个函数方法,去实现业务逻辑),它们被事先编译好并且存储在数据库中。

  调用存储过程与直接执行 SQL 语句的效果是相同的,但是存储过程的一个好处是处理逻辑都封装在数据库端。

  当我们调用存储过程的时候,我们不需要了解其中的处理逻辑,一旦处理逻辑发生变化,只需要修改存储过程即可,对调用它的程 序完全无影响。

  调用存储过程和函数可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,减少了和脚本语言的交互以及带宽,可以提高数据处理的效率。

 
二、存储过程结构

 

create procedure 【存储过程名(参数列表)】
begin【存储过程体】
end

 

call 存储过程名(参数列表)


 

 
三、使用示例

 
实例1、新建一张数据表,并向这张数据表中添加 100 万条记录。

(1)新建数据表

CREATE TABLE `test_table` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,`loop` int(10) unsigned NOT NULL DEFAULT '0',`name` varchar(256) NOT NULL DEFAULT '',`pen_name` varchar(256) NOT NULL DEFAULT '',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


(2)新建存储过程

DROP PROCEDURE IF EXISTS insert_many_rows;CREATE PROCEDURE insert_many_rows (IN loopTime INT)
BEGINDECLARE executedTime INT ;SET executedTime = loopTime;while executedTime > 0 DOINSERT INTO test_table(NULL, 0, 'sss', 'kkk');SET executedTime = executedTime - 1;END WHILE;
END;


(3)呼叫存储过程

CALL insert_many_rows(1000000);

结果应该是新建的数据表中已经有了 100 万条记录。

 
实例2:通过存储过程创建10个数据表,分别为test_table_0 ~ test_table_9

(1)创建存储过程

DROP PROCEDURE IF EXISTS create_test_tables;
CREATE PROCEDURE `create_test_tables`()
BEGINDECLARE i INT;DECLARE tableName VARCHAR(30);DECLARE sqlText text;SET i = 0;WHILE i < 10 DOSET tableName = CONCAT('test_table_' , i);SET sqlText = CONCAT('CREATE TABLE ', tableName , '(`id` int(10) unsigned NOT NULL AUTO_INCREMENT,`loop` int(10) unsigned NOT NULL DEFAULT ''0'',`name` varchar(256) NOT NULL DEFAULT '''',`pen_name` varchar(256) NOT NULL DEFAULT '''',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2001001 DEFAULT CHARSET=utf8;');SET @sqlText = sqlText;PREPARE stmtFROM@sqlText;EXECUTE stmt;DEALLOCATE PREPARE stmt;SET i = i + 1;END WHILE;
END


(2)呼叫存储过程

CALL create_test_tables();


 
 四、分析

 
1、存储过程的参数类型:

(1)IN 表示只是用来输入。

(2)OUT 表示只是用来输出。

(3)INOUT 可以用来输入,也可以用作输出。

 
2、存储过程中的变量声明

通过 DECLARE 来声明一个局部变量,该变量的作用域只是 begin....end 块中。

变量的声明可以添加默认值,比如:

DECLARE executedTime INT DEFAULT 0;

 
3、流程控制语句语法

if 的语法格式为:
if 条件表达式 then 语句[elseif 条件表达式 then 语句] ....[else 语句]
end ifcase 的语法格式
首先是第一种写法:
case 表达式when 值 then 语句when 值 then 语句...[else 语句]
end case
然后是第二种写法:
casewhen 表达式 then 语句when 表达式 then 语句....[else 语句]
end caseloop 循环 语法格式为:
[标号:] loop循环语句
end loop [标号]while 语法
while a>100 do循环语句
End whileRepeat        //游标SQL语句1UNTIL 条件表达式
END Repeat;LoopSQL语句所有的条件判断和跳出需要自己实现
End loopleave 语句用来从标注的流程构造中退出,它通常和 begin...end 或循环一起使用
leave 标号;声明语句结束符,可以自定义:
DELIMITER [符合]
delimiter $$

 
4、存储过程中的数据类型

数值类型:Int、float、double、decimal

日期类型:timestamp、date、year

字符串:char、varchar、text


五、存储过程优缺点

 
1、优点:

(1)执行速度快。因为我们的每个 SQL 语句都需要经过编译,然后再运行。但是存储过程都是直接编译好了之后,直接运行即可。

(2)减少网络流量,我们传输一个存储过程比我们传输大量的 SQL 语句的开销要小得多。

(3)提高系统安全性,因为存储过程可以使用权限控制,而且参数化的存储过程可以有效地防止 SQL 注入攻击。保证了其安全性。

(4)耦合性降低。当我们的表结构发生了调整或变动之后,我们可以修改相应的存储过程,我们的应用程序在一定程度上需要改动的地方就较小了。

(5)重用性强,因为我们写好一个存储过程之后,再次调用它只需要一个名称即可,也就是”一次编写,随处调用”,而且使用存储过程也可以让程序的模块化加强。

 
2、缺点:

(1)可移植性差。因为存储过程是和数据库绑定的,如果我们要更换数据库之类的操作,可能很多地方都需要改动。

(2)修改不方便。因为对于存储过程而言,我们并不能特别有效的调试,它的一些 bug 可能发现的更晚一些,增加了应用的危险性。

(3)优势不明显和赘余功能。对于小型 web 应用来说,如果我们使用语句缓存,发现编译 SQL 的开销并不大,但是使用存储过程却需要检查权限一类的开销,这些赘余功能也会在一定程度上拖累性能。

 
六、PHP 中使用存储过程

PHP 中也是可以使用存储过程的,存储过程的使用也很简单。只要将存储过程的创建语句和call语句分别执行就可以了。

这里使用最简单的 pdo 调用方式,如果在框架中,为了保持代码的美观,请使用框架自带的查询执行语句。```
 

<?php
declare(strict_types = 1);// 注意:创建存储过程和call存储过程要分开执行,创建存储过程之后,将创建存储过程部分注释掉,然后打开call存储过程代码执行// 连接 pdo
$dsn = "mysql:dbname=test;host=127.0.0.1";
$pdo = new PDO($dsn,'root','123456');# ------------------------------- 创建存储过程 --------------------------
// 创建存储过程语句赋值到变量
$sql = 'DROP PROCEDURE IF EXISTS insert_many_rows_2;
CREATE PROCEDURE insert_many_rows_2 (IN loopTime INT)
BEGINDECLARE executedTime INT ;SET executedTime = loopTime;while executedTime > 0 DOINSERT INTO test_table(NULL, 0, \'sss\', \'kkk\');SET executedTime = executedTime - 1;END WHILE;
END;';// 执行
$stmt = $pdo->query($sql);
var_dump($stmt->fetchAll(2));#---------------------- call 存储过程 --------------------------/*$callSql = 'CALL insert_many_rows(1000000);';
$stmt = $pdo->query($callSql);
var_dump($stmt->fetchAll(2));*/

 

七、总结

存储过程只做了解即可,事实上很多公司都是禁止使用存储过程的,主要是因为一旦使用存储过程,新人接手将会非常困难,并且难以调试和扩展,而且没有可移植性。

何况存储过程能够解决的问题,一般程序代码也是可以解决的,因此在非必要情况下,还是使用代码去实现,而不是考虑去用存储过程。

 

原文链接:https://www.haveyb.com/article/61

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/282125.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

白话聊应用架构

产业互联网时代&#xff0c;数字化转型&#xff08;数字化演化历史&#xff09;已成为一种趋势&#xff0c;各行各业都投入到数字化转型的浪潮中来。节后有个客户项目参与者问我架构方面的事情&#xff0c;我想来想去对于非IT人来说&#xff0c;可能应用架构是最容易理解&#…

python大数_python处理大数字的方法

本文实例讲述了python处理大数字的方法。分享给大家供大家参考。具体实现方法如下&#xff1a;def getFactorial(n):"""returns the factorial of n"""if n 0:return 1else:k n * getFactorial(n-1)return kfor k in range(1, 70):print "…

数据库分库分表、读写分离的原理和实现,以及使用场景

2019独角兽企业重金招聘Python工程师标准>>> 为什么要分库分表和读写分离&#xff1f; 类似淘宝网这样的网站&#xff0c;海量数据的存储和访问成为了系统设计的瓶颈问题&#xff0c;日益增长的业务数据&#xff0c;无疑对数据库造成了相当大的负载&#xff0c;同时…

谈谈一些有趣的CSS题目(十六)-- 奇妙的 background-clip: text

开本系列&#xff0c;谈谈一些有趣的 CSS 题目&#xff0c;题目类型天马行空&#xff0c;想到什么说什么&#xff0c;不仅为了拓宽一下解决问题的思路&#xff0c;更涉及一些容易忽视的 CSS 细节。 解题不考虑兼容性&#xff0c;题目天马行空&#xff0c;想到什么说什么&#x…

第五周软件工程作业-每周例行报告

一、PSP T名称C内容ST开始时间ED结束时间中断时间/min实际时间/minScrum会议第一次Scrum会议10月13日11:3010月13日12:10040第二次Scrum会议10月14日15:3010月14日15:55025第三次Scrum会议10月15日13:3010月15日14:05035第四次Scrum会议10月16日11:3010月16日13:00090第五次Scr…

MySQL - 触发器

一、概述 Mysql 允许通过触发器、存储过程、函数的形式来存储代码。 触发器可以让你在执行 Insert、Update、Delete的时候&#xff0c;执行一些特定的操作。可以在Mysql中指定是在Sql语句执行之前触发还是执行后触发。 二、使用触发器需要注意的点 对每一个表的每一个事件&a…

Docker Desktop 可以直接启用Kubernetes 1.25 了

作为目前事实上的容器编排系统标准&#xff0c;K8s 无疑是现代云原生应用的基石&#xff0c;很多同学入门可能直接就被卡到第一关&#xff0c;从哪去弄个 K8s 的环境&#xff0c; Docker Desktop 自带了Kubernetes 服务&#xff0c;但是在过往的经验中就是用梯子也安装不了&…

截取url的host_java正则表达式获取url的host示例

java正则表达式获取url的host示例 复制代码 代码如下: public static String getHost(String url){if(url==null||url.trim().equals("")){return ""; } String host = ""; Pattern p = Pattern.compile("(?<=//|)((\\w)+\\.)+\\w+&qu…

MySQL - 视图

一、概述 Mysql 5.0 版本后开始引入视图。视图本身是一个虚拟表&#xff0c;不存放任何数据。在使用 sql 语句访问视图的时候&#xff0c;他返回的数据都是在查询过程中从其他表动态生成的。 二、使用视图   1、创建视图 CREATE VIEW comic_view as SELECT comic_id,name,pe…

Linux环境下压缩与解压命令大全

tar命令 解包&#xff1a;tar zxvf FileName.tar 打包&#xff1a;tar czvf FileName.tar DirName gz命令 解压1&#xff1a;gunzip FileName.gz 解压2&#xff1a;gzip -d FileName.gz 压缩&#xff1a;gzip FileName .tar.gz 和 .tgz 解压&#xff1a;tar zxvf FileName.tar.…

Centos 磁盘管理及配额管理

实验内容&#xff1a;一.添加两块硬盘&#xff0c;使用LVM做成VG01组&#xff0c;在该VG中新建两个LV。二.将这两个LV格式化为ext4/xfs&#xff0c;开机自动挂载到系统mnt1,mnt2目录下。三.lv02开启磁盘配额功能&#xff0c;用来进行用户与组分配额的实验。四.在系统里添加用户…

OnionArch - 采用DDD+CQRS+.Net 7.0实现的洋葱架构

博主最近失业在家&#xff0c;找工作之余&#xff0c;看了一些关于洋葱&#xff08;整洁&#xff09;架构的资料和项目&#xff0c;有感而发&#xff0c;自己动手写了个洋葱架构解决方案&#xff0c;起名叫OnionArch。基于最新的.Net 7.0 RC1, 数据库采用PostgreSQL, 目前实现了…

spark写出分布式的训练算法_利用 Spark 和 scikit-learn 将你的模型训练加快 100 倍...

在 Ibotta&#xff0c;我们训练了许多机器学习模型。这些模型为我们的推荐系统、搜索引擎、定价优化引擎、数据质量等提供动力。它们在与我们的移动应用程序交互时为数百万用户做出预测。当我们使用 Spark 进行数据处理时&#xff0c;我们首选的机器学习框架是 scikit-learn。随…

理解LinkedHashMap

1. LinkedHashMap概述&#xff1a;LinkedHashMap是HashMap的一个子类&#xff0c;它保留插入的顺序&#xff0c;如果需要输出的顺序和输入时的相同&#xff0c;那么就选用LinkedHashMap。LinkedHashMap是Map接口的哈希表和链接列表实现&#xff0c;具有可预知的迭代顺序。此实现…

MySQL - 锁

一、什么是锁 锁是数据库系统区别于文件系统的一个关键特性。锁机制用于管理对共享资源的并发访问。 二、MySQL 不同存储引擎支持的锁机制 存储引擎支持的锁类型Myisam表锁Innodb行锁、表锁Memory表锁BDB页锁、表锁表锁&#xff1a;直接锁住的是一个表&#xff0c;开销小&…

数据库时区那些事儿 - MySQL的时区处理

原文地址 当JVM时区和数据库时区不一致的时候&#xff0c;会发生什么&#xff1f;这个问题也许你从来没有注意过&#xff0c;但是当把Java程序容器化的时候&#xff0c;问题就浮现出来了&#xff0c;因为目前几乎所有的Docker Image的时区都是UTC。本文探究了MySQL及其JDBC驱动…

java_函数的重载

函数的重载&#xff08;Overload&#xff09;概念&#xff1a;在同一个类中&#xff0c;允许存在一个以上的同名函数&#xff0c;只要他们的参数个数或者参数类型不同即可。函数功能一样&#xff0c;仅仅是参与运算的未知内同不同时&#xff0c;可以定义多函数&#xff0c;却使…

全新升级的AOP框架Dora.Interception[2]: 基于约定的拦截器定义方式

Dora.Interception&#xff08;github地址&#xff0c;觉得不错不妨给一颗星&#xff09;有别于其他AOP框架的最大的一个特点就是采用针对“约定”的拦截器定义方式。如果我们为拦截器定义了一个接口或者基类&#xff0c;那么拦截方法将失去任意注册依赖服务的灵活性。除此之外…

redis watch使用场景_redis不得不会的事务玩法

我们都知道redis追求的是简单&#xff0c;快速&#xff0c;高效&#xff0c;在这种情况下也就拒绝了支持window平台&#xff0c;学sqlserver的时候&#xff0c;我们知道事务还算是个比较复杂的东西&#xff0c;所以这吊毛要是照搬到redis中去&#xff0c;理所当然redis就不是那…

加快Android Studio的编译速度

从Eclipse切换到Android Studio后&#xff0c;感觉Android Studio的build速度比Eclipse慢很多&#xff0c;以下几个方法可以提高Android Studio的编译速度使用Gradle 2.4Gradle 2.4对执行性能有很大的优化&#xff0c;但Android Studio现在默认使用的是Gradle 2.2,所以我们需要…