码迷,mamicode.com
首页 > 数据库 > 详细

MySQL存储过程

时间:2016-12-14 07:37:08      阅读:410      评论:0      收藏:0      [点我收藏+]

标签:方法   limit   bool   sof   类型   ref   循环   依次   roo   

含义

存储过程类似一个函数,数据库中也支持循环语句和判断语句。我们可以将所有的逻辑、判断和SQL语句全部写在数据库上面,然后取个名字,当程序来操作的时候,可以直接通过这个名字,就能执行对应的功能;不用传大量的SQL语句。

 

存储过程

一、创建存储过程

关键字: procedure

代码:

create procedure proc_p1()

说明:

  • create procedure:表示要创建存储。
  • proc_p1:是创建存储的名字。

这样就创建了一个存储过程,名为proc_p1;但是此时里面并没内容。

二、创建存储过程内容

代码:

create procedure proc_p1()
begin
内容放置位置
end

说明:
要操作的内容必须放在,begin和end之间。

案例:

数据库内容:

技术分享

操作代码:

create procedure proc_p1()
BEGIN
select * from part;
END

结果;生成的对象会存储在函数中;

技术分享

三、调用存储过程

关键字:CALL

代码:

CALL proc_p1();

四、删除存储过程

代码:

drop procedure proc_p1;

问题:能否修改存储过程那?

答案是肯定的,但是却很繁琐,因此我们一般修改的时候,都是重写存储过程。

因此,针对修改我们的操作(也是重写):

技术分享
delimiter $$drop procedure proc_p1 $$
create procedure proc_p1()
BEGIN
  select * from part;
END $$delimiter ;
代码

分析:
即先删除,后写入。

问题:如果删除的时候,没有对应的存储过程那?

答案:会报错!
因此我们要避险这种情况出现。

技术分享
delimiter $$drop procedure if EXISTS proc_p1 $$
create procedure proc_p1()
BEGIN
  select * from part;
END $$delimiter ;
代码

分析:
增加了if EXISTS判断;它表示,如果后面的这个存储过程有则删除,反之不操作;这样避免报错,导致问题。

上面的代码都是简单的操作,再看下面的代码:

 

有参数的存储过程

一、参数 in

技术分享
delimiter $$drop procedure if EXISTS proc_p1 $$
create procedure proc_p1(
  in i1 int
)
BEGIN
declare d1 int;
declare d2 int default 2;
set d1 = i1 + d2;
END $$delimiter ;
in

分析:
in:表示进的,接收参数
declare:表示声变量。
int:表示变量类型
default:表示设置变量的初始值。
set:表示赋值操作,也可以理解为设置值。

自定义代码的结束符号

delimiter

drop procedure if EXISTS proc_p1;
create procedure proc_p1()
BEGIN
select * from part;
END

上面代码在Navicat下是能执行的,但是在终端上是要出问题的。
原因就是这个分号;上面的代码begin和end间代码,表示一个功能,都是整体传进去的,但是,代码在执行的时候,遇到分号;则表示此功能的代码执行完毕。所以导致后面的代码不执行,在终端的运行,因为分号的原因,会导致运行的时候出问题,所以,分号要是用在不对的位置,会造成很大的麻烦。

说明:
这个的意思就表示,以后的mysql语句都是以 $$为结束。

注意:

自定义的时候不能将 \\ 设置用来结束;\\ 在终端会报错!可能是转义符的原因吧。

验证上面的说明:

在终端进入mysql客户端,当我们输入的代码不带分号的时候,结果,会一直处于等待命令的状态:

技术分享

 

加上分号:出结果

技术分享

问题:如果我们这样改动的话,获导致全局都受影响,因此我们可以让这种效果,只在指定范围有效,离开这个范围,有还原会之前?

所以,完整的代码:

技术分享
delimiter $$
drop procedure if EXISTS proc_p1 $$
create procedure proc_p1(
in i1 int
)
BEGIN
declare d1 int;
declare d1 int;
set d1 = i1 + d2;
END $$
delimiter ;
完整代码

说明:

我们在end后加上 $$ 表示一个功能的代码结束,并在最后,又将设置还原会去。还是以分号结尾,这样其他代码不受影响

 

下面接着存储参数in分析

二、参数 out

代码:

技术分享
delimiter $$
drop procedure if EXISTS proc_p1 $$
create procedure proc_p1(
in i1 int,
out i2 int
)
BEGIN
declare d2 int default 3;
if i1 = 1 then
set i2 = 100 + d2;
elseif i1 = 2 THEN
set i2 = 200 + d2;
else
set i2 = 1000 + d2;
end if;
END $$
delimiter ;

-- 加入回话变量 @u;
call proc_p1(1, @u);

select @u;
out

结果:

技术分享

  • 说明:
    @u:默认其值为 none;回话变量,相当于我们在外面创建了一个变量,并将引用传入 proc_p1函数,这个传入的引用会被 i2 接收,所以,间接的也相当于在给这个 @u 赋值。
  • out:字面意思理解,出;有返回的意思。

三、参数 inout

技术分享
delimiter $$
drop procedure if EXISTS proc_p1 $$
create procedure proc_p1(
in i1 int,
inout ii int,
out i2 int
)
BEGIN
declare d2 int default 3;
if i1 = 1 then
set i2 = 100 + d2;
set ii = ii + 1;
elseif i1 = 2 THEN
set i2 = 200 + d2;
else
set i2 = 1000 + d2;
end if;
END $$
delimiter ;

-- 加入回话变量 @u;

set @o = 5;
call proc_p1(1, @o, @u);

select @o,@u;
inout

结果:

技术分享

分析:
inout:从字面意思理解”进、出”,表示要接收一个带值的变量,同时函数执行完后,也会将对应的变量返回。

扩展:sql中@变量

带上一个@叫用户变量:只要用户还登录着,这个变量就有效;不管在那个代码块中都有效;除非用户被关闭。

带上2个@叫全局变量。

注意:用户变量和函数的局部变量的区别

  • 用户变量:只要用户还登录着,这个变量就有效;不管在那个代码块中都有效;除非用户被关闭。
  • 局部变量:离开函数就没用了。

python操作数据库存储过程

技术分享
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import pymysql

conn = pymysql.connect(host=‘127.0.0.1‘, port=3306, user=‘root‘, passwd=‘123‘, db=‘t1‘)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
# 执行存储过程
cursor.callproc(‘proc_p1‘, (1,2,3))
# 获取执行完存储的参数
cursor.execute("select @_p1_0,@_p1_1,@_p1_2,@_p1_3")
result = cursor.fetchall()

conn.commit()
cursor.close()
conn.close()

print(result)
代码

说明:
cursor.callproc(‘proc_p1’, (1,2,3)):只能给数据库中的proc_p1存储方法;根据前面的我们知道数据库中的proc_p1;只能接收2个参数,所以,即使你传入了3个也只有2个能用。后面的会自动忽略。

上面的数据库中的存储过程,没有SQL语句,只是简单的,变量操作,但是,如果我们加入SQL操作,那我们在python中怎样获取这个SQL语句操作的结果那?

 

获取存储过程的查询结果:

cursor.fetchall()

 问题:怎样获取变量的返回值那?

cursor.execute("select @_p1_0”)

分析:
1、首先要用select
2、一个@_
3、后面在接存储过程的名字。
4、接 _0:表示索引。表示获取返回第一个值,要想获取后面的,则依次往后指定,用逗号隔开便可。

cursor.execute("select @_p1_0,@_p1_1,@_p1_2,@_p1_3")

这个获取获的值,存放在游标里面的,所以,要获取具体的值,可以通过游标结合fetchone获取:

result = cursor.fetchone()

特殊:
虽然存储过程中,in接收参数,但是在python中获取存储过程数据的时候,in接收传入的值,会被返回,所以,获取的第一个值,便是,callproc执行的时候,传入的第一个参数.

python获取存储过程分两步:

  • 获取SQL语句执行的返回值
  • 获取存储函数的变量返回值

 技术分享

MySQL存储过程

标签:方法   limit   bool   sof   类型   ref   循环   依次   roo   

原文地址:http://www.cnblogs.com/jayafs/p/6175770.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!