ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

数据库之存储过程

2021-02-27 22:36:52  阅读:192  来源: 互联网

标签:存储 调用 int 数据库 pymysql cursor 过程 procedure


存储过程

1.什么是存储过程?

存储过程就类似于python中的自定义的函数,它的内部包含了一系列可以执行的sql语句,存储过程存放于mysql服务端中,你可以直接通过调用存储过程触发内部sql语句的执行

2.存储过程的基本使用

procedure /prəˈsiːdʒə(r) 程序, 过程

-- 创建语法
delimiter //
create procedure 存储过程的名字([形参1,形参2,...])
begin
	sql代码
end //
delimiter ;

-- mysql 中调用存储过程语法
call 存储过程的名字([实参1,实参2,...]);

-- python中基于pymysql调用
cursor.callproc("存储过程的名字")
print(cursor.fetchall())

3.三种开发模式: 程序与数据库结合开发

# 第一种
"""  
应用程序: 程序员写业务代码开发
mysql: dba提前编写好存储过程,供应用程序调用
好处: 开发效率提升了,执行效率也上去了
缺点: 考虑到人为因素,需要跨部门沟通问题,后续的存储过程的扩展性差
"""

# 第二种
"""
应用程序: 程序员写代码开发之外 涉及到数据库操作也要自己手写
优点: 解决了跨部门不方便扩展的问题
缺点: 开发效率低,都是程序员干活.程序员不仅要会多种编程语言,还要考虑sql语句的执行效率问题
"""

# 第三种
"""
应用程序: 程序员只写程序代码 不写sql语句了.而是用别人写好的操作sql的框架即可
比如: 后面要讲的ORM框架对象关系映射
优点: 开发效率比前俩种开发效率都要高
缺点: 语句的扩展性差,可能会出现效率低下的问题.
"""
# 第一种基本不用,一般都是第三种方法,当出现效率低下的情况,再去手动的写一些sql语句

4.创建存储过程并调用(无参)

创建库并准备表和数据

create database procedure_test charset utf8;
use procedure_test;

CREATE TABLE blog (
    id INT PRIMARY KEY auto_increment,
    NAME CHAR (32),
    sub_time datetime
);

INSERT INTO blog (NAME, sub_time)
VALUES
    ('第1篇','2015-03-01 11:31:21'),
    ('第2篇','2015-03-11 16:31:21'),
    ('第3篇','2016-07-01 10:21:31'),
    ('第4篇','2016-07-22 09:23:21'),
    ('第5篇','2016-07-23 10:11:11'),
    ('第6篇','2016-07-25 11:21:31'),
    ('第7篇','2017-03-01 15:33:21'),
    ('第8篇','2017-03-01 17:32:21'),
    ('第9篇','2017-03-01 18:31:21');

mysql种创建及调用

delimiter //
create procedure p1()
begin
	select * from blog;
	insert into blog(name,sub_time) values('ldsb',now());
end //
delimiter ;

# 调用
call p1();

python中基于pymysql调用

import pymysql

conn = pymysql.connect(
	host = '127.0.0.1',
    port=3306,
    user='root',
    password='jzd123',
    database='procedure_test',
    charset='utf8'
)

cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

# 在python中 通过游标下的callproc方法调用存储过程p1
cursor.callproc('p1')
print(cursor.fetchall())

cursor.close()
conn.close()

5.创建存储过程并调用(有参)

对于存储过程, 可以接受参数,其参数有三类

in , out 和 inout

-- n n int      ---> 声明变量n为外部传入的值, 类型为int. 可以为存储过程定义的形参in直接传值,
-- out res int  ---> 声明变量res为返回值, 类型为int. 为存储过程定义的形参out传值, 需要实现使用set声明才能传.
-- inout x int  --->  声明变量x既能收值又能返回值. 虽然inout既能接收又能充当返回值, 但是为了保证int和out的传值的统一性, 因此也需要事先使用set声明才能传.
  • in: 传入参数
Copydelimiter //
create procedure p2(
    in n1 int,
    in n2 int
)
BEGIN
    select * from blog where id > n1;
END //
delimiter ;


# 在mysql中调用
call p2(3,2)

# 在python中基于pymysql调用
cursor.callproc('p2',(3,2))
print(cursor.fetchall())
  • out:返回值
Copydelimiter //
create procedure p3(
    in n1 int,
    out res int
)
BEGIN
    select * from blog where id > n1;
    set res = 1;
END //
delimiter ;

# 在mysql中调用
set @res=0;       # 定义全局变量用于给out定义的res形参. 0代表假(执行失败),1代表真(执行成功).
call p3(3,@res);  # 调用存储过程
select @res;      # 查看存储过程

# 在python中基于pymysql调用
cursor.callproc('p3',(3,0)) # 0相当于set @res=0
print(cursor.fetchall())    #查询select的查询结果

cursor.execute('select @_p3_0,@_p3_1;') # @p3_0代表第一个参数,@p3_1代表第二个参数,即返回值
print(cursor.fetchall()
  • inout: 既可以传入又可以返回
Copydelimiter //
create procedure p4(
    inout n1 int
)
BEGIN
    select * from blog where id > n1;
    set n1 = 1;
END //
delimiter ;

#在mysql中调用
set @x=3;
call p4(@x);
select @x;


# 在python中基于pymysql调用
cursor.callproc('p4',(3,))
print(cursor.fetchall()) # 查询select的查询结果

cursor.execute('select @_p4_0;') 
print(cursor.fetchall())

6. 执行存储过程: int+out

  • 创建库并准备表和数据
Copydrop database procedure_test;  # 小心
create database procedure_test charset utf8;
use procedure_test;

create table emp(
  id int not null unique auto_increment,
  name varchar(20) not null,
  sex enum('male','female') not null default 'male', #大部分是男的
  age int(3) unsigned not null default 28,
  hire_date date not null,
  post varchar(50),
  post_comment varchar(100),
  salary double(15,2),
  office int, #一个部门一个屋子
  depart_id int
);

#插入记录
#三个部门:教学,销售,运营
insert into emp(name,sex,age,hire_date,post,salary,office,depart_id) values
('jason','male',18,'20170301','张江第一帅形象代言',7300.33,401,1), #以下是教学部
('tom','male',78,'20150302','teacher',1000000.31,401,1),
('kevin','male',81,'20130305','teacher',8300,401,1),
('tony','male',73,'20140701','teacher',3500,401,1),
('owen','male',28,'20121101','teacher',2100,401,1),
('jack','female',18,'20110211','teacher',9000,401,1),
('jenny','male',18,'19000301','teacher',30000,401,1),
('sank','male',48,'20101111','teacher',10000,401,1),
('哈哈','female',48,'20150311','sale',3000.13,402,2),#以下是销售部门
('呵呵','female',38,'20101101','sale',2000.35,402,2),
('西西','female',18,'20110312','sale',1000.37,402,2),
('乐乐','female',18,'20160513','sale',3000.29,402,2),
('拉拉','female',28,'20170127','sale',4000.33,402,2),
('僧龙','male',28,'20160311','operation',10000.13,403,3), #以下是运营部门
('程咬金','male',18,'19970312','operation',20000,403,3),
('程咬银','female',18,'20130311','operation',19000,403,3),
('程咬铜','male',18,'20150411','operation',18000,403,3),
('程咬铁','female',18,'20140512','operation',17000,403,3);
  • mysql中创建及调用
Copydrop procedure p1;

# 定义存储过程
delimiter $$
create procedure p1(
    in m int,  # 该形参m只负责接收值, m不能当作参数返回。
    in n int,  
    out res int  # 该形参res只负责返回值,不能直接接收参数,需要使用set先定义变量。 针对out存储过程的返回值参数一定要设置一个变量, 通常用返回值判断你这天sql语句运行成功与否, 返回值为0通常代表成功
)
begin
    select tname from teacher where tid>m and tid<n;
    set res=0;  # 将res变量修改, 用来标识当前的存储过程代码确实执行了。(修改成啥都行)
end  $$
delimiter ;

# 定义变量
set @xxx=10;  # 争对形参res不能直接传数据,因该传一个变量命。

# 查看变量对应得值
set @xxx;

# 调用存储过程
"""
第一个第二个参数: 为存储过程in定义的参数传值
第二个参数: 为存储过程out定义的返回值传值, out需要使用set声明才能传
"""
call p1(1, 10, @xxx);

# 删除存储过程
drop procedure p1;
  • pymysql模块使用存储过程
Copyimport pymysql

conn = pymysql.connect(
    host='127.0.0.1',
    port=3306,
    user='root',
    password='jzd123',
    database='procedure_test',
    charset='utf8',
)

cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

# 调用存储过程
cursor.callproc('p1', (1, 5, 10))
"""
pymysql底层实现. 
set @_p1_0 = 1
set @_p1_1 = 5
set @_p1_2 = 10
"""
print(cursor.fetchall())  

# 执行select语句验证
cursor.execute('select @_p1_0')  
print(cursor.fetchall())  # [{'@_p1_0:1'}]

cursor.close()
conn.close()

7. 删除存储过程

Copydrop procedure 存储过程的名字;

标签:存储,调用,int,数据库,pymysql,cursor,过程,procedure
来源: https://www.cnblogs.com/jkeykey/p/14457468.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有