关于mysql 的存储过程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于mysql 的存储过程相关的知识,希望对你有一定的参考价值。

编写存储过程的时候 分号可不可以用
一用分号 就默认命令已经结束
该怎么办
比如
我用declare c int ;
一写到这里 就结束了
顺便问一下 mysql 是不是不支持缩写 总是提示int 是一个错误?
难道没人知道吗

mysql> delimiter //
这个作用是把;变成//,以后的语句遇到//就结束了,遇到;不结束,下面就可以按你的想法写了

mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)
-> BEGIN
-> SELECT COUNT(*) INTO param1 FROM t;
-> END
-> //
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ; 这里把双引号改回来

声明参数要在说明是 输入还是输出函数 in\out

给函数变量赋值用
set @a=10;

例子:

drop procedure if exists pr_param_in;

create procedure pr_param_in
(
in id int -- in 类型的 MySQL 存储过程参数
)
begin
if (id is not null) then
set id = id + 1;
end if;

select id as id_inner;
end;
set @id = 10;

call pr_param_in(@id);

select @id as id_out;
mysql> call pr_param_in(@id);
参考技术A 呵呵,没看到...
BEGIN
/*取上次计算的时间*/
select @count_time=max(cast(nvc_accounttime as datetime)) from stat_day_photo;
/*设置计算开始时间*/
if @count_time is null then
select @start_time=min(createtime) from stat_log_photo;
else
select @start_time=@count_time;
end if;
/*设置计算结束时间*/
select @end_time=cast(cast(date_add(now(),interval 1 day) as char(16))as datetime);
/*按有记录时间取得计算一天的起止时间,如果今天已经计算过就再计算一次,允许重复计算今天*/
select @t_start_time=cast(cast(@start_time as char(10)) as datetime);
if @t_start_time=date_add(curdate(),interval 1 day) then
select @t_start_time=curdate();
end if;
select @t_end_time=date_add(@t_start_time,interval 1 day);
/*计算以前的访问情况*/
while @t_end_time<=@end_time do
/*判断是否有相关记录*/
select @have_record=count(1) from stat_day_photo where Nvc_AccountTime=cast(@t_end_time as char(16));
/*如果没有记录,补充一条*/
if @have_record>0 then
delete from stat_day_photo where Nvc_AccountTime=cast(@t_end_time as char(16));
end if;

/*建临时数据表,在进行分别计算时,在外边统一处理,不用单独做*/
DROP TABLE IF EXISTS `m_log`;
SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `m_log` (
`ID` bigint(20) NOT NULL auto_increment,
`pid` bigint(20) NOT NULL ,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
/*在分别计算时使用*/
delete from m_log;
insert into m_log(pid) select I_photoID from stat_log_photo where createtime >= @t_start_time and createtime < @t_end_time group by I_photoID order by count(1) desc;
select @min_id=min(id),@max_id=max(id) from m_log;
while @min_id<=@max_id do
/*取作品ID*/
select @mainID=pid from m_log where id=@min_id;

/*取当天的数量,浏览量、IP数*/
select @views=count(1) from stat_log_photo where createtime>=@t_start_time and createtime<@t_end_time and I_photoID=@mainID;
select @ips=count(distinct nvc_ip) from stat_log_photo where createtime>=@t_start_time and createtime<@t_end_time and I_photoID=@mainID;

/*更新数据*/
insert into stat_day_photo(I_photoID,I_visits,I_ips,Nvc_AccountTime) values(@mainID,@views,@ips,cast(@t_end_time as char(16)));
select @min_id=@min_id+1;
end while;
select @t_start_time=@t_end_time;
select @t_end_time=date_add(@t_end_timee,interval 1 day);
end while;
END

看看这个例子
我写过的一个mysql存储过程
对你应该有帮助
参考技术B 修改结束符
delimiter $
create procedure.....

end$
delimiter;
简易用sqlyog,写过程蛮好用的

MySQL---存储过程复习


存储过程

  • 存储过程,带有逻辑的sql语句
  • 之前的sql没有条件判断,没有循环
  • 存储过程带上流程控制语句(if while)

特点

  • 存储过程是在数据库的服务器端执行的,效率很高
  • 移植性很差,不同数据库的存储过程是不能移植的,消耗服务器的资源

基本语法格式

DELIMITER $ #声明结束标记
CREATE PROCEDURE 存储过程名(
[IN 参数名 数据类型,参数名 数据类型...],[OUT 参数名 数据类型,参数名 数据类型...],
[INOUT 参数名 数据类型,参数名 数据类型...]
)
BEGIN 

[DECLARE 变量名 数据类型 DEFAULT 初始值;]

执行的逻辑,包括SQL语句

END $

关于存储过程的参数


1.输入参数

CREATE PROCEDURE 存储过程名(IN 参数名 数据类型,参数名 数据类型...)

2.输出参数

CREATE PROCEDURE 存储过程名(OUT 参数名 数据类型,参数名 数据类型...)

3.输入参数输出参数可以一起使用

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

4.INOUT输入输出参数,具有in和out的双重功能

CREATE PROCEDURE 存储过程名(INOUT 参数名 数据类型,参数名 数据类型...)

示例

DELIMITER $
CREATE PROCEDURE myp1()
BEGIN
         DECLARE boyName VARCHAR(20)  DEFAULT '大忽悠';
         SELECT boyName;
END $
#调用
CALL myp1();


1.使用in参数

DELIMITER $
CREATE PROCEDURE getname(IN id INT(100))
BEGIN
         SELECT p.serial FROM payment p WHERE p.id=id; 
END $
#调用
CALL getname(1);


2.创建带输入和输出参数的存储过程

DELIMITER $
#两个输入参数,一个输出参数
CREATE PROCEDURE concatStr(IN s1 VARCHAR(50),IN s2 VARCHAR(50),OUT ret VARCHAR(50))
BEGIN
#拼接参数,设计局部变量的值
        SET ret=CONCAT(s1,"--->",s2);
END $

#声明一个局部变量,用来接收输出参数的结果
SET @res :="";

#调用
CALL concatStr("小朋友","大忽悠",@res);

#打印输出参数的结果
SELECT @res;


注意

使用有输出参数(有返回值)的存储过程

  • 我们要现在外面定义变量来接收存储过程输出参数 set @变量名 := 变量的初始化值
  • 在调用存储过程时,把定义的变量当做实参放在call调用存储过程函数的对应输出参数位置----([输入值…],[@变量名])
  • 变量在接受到存储过程的返回值(输出值)就可以直接使用了,例如查询输出变量(select @变量名)

3.使用INOUT参数,具有in和out的双重功能

DELIMITER $
CREATE PROCEDURE myp8(INOUT a INT,INOUT b INT)
BEGIN
        SET a=a*2;
        SET b=b*2;
END $

#调用
SET @m=10;
SET @n=20;
CALL myp8(@m,@n);
SELECT @m,@n;


4.存储过程使用局部变量

DELIMITER $
CREATE PROCEDURE myp1(IN NAME VARCHAR(20))
BEGIN
#声明一个局部变量
         DECLARE uoionname VARCHAR(20)  DEFAULT '大忽悠';
         SET uoionname=CONCAT(NAME,"和",uoionname);   
         SELECT  uoionname;
END $
#调用
CALL myp1("小朋友");


5.使用 [ select 字段 into变量 ] 把查询的结果赋值给变量

DELIMITER $
CREATE PROCEDURE myp3(OUT NAME VARCHAR(20))
BEGIN
#声明一个局部变量
SELECT SERIAL INTO NAME FROM payment WHERE id =1;
END $

#调用
SET @NAME="";
CALL myp3(@NAME);
SELECT @NAME;


存储过程中的流程控制

IF语句

如果,否则

IF...THEN...ELSE...END IF

如果,如果,…否则

IF...THEN...ELSEIF...THEN...ELSEIF...THEN....ELSE...END IF

例子:

DELIMITER $
CREATE PROCEDURE pass(IN i INT(10))
BEGIN

#if语句
IF i<=0 THEN 
SELECT "不通过";
ELSE
SELECT "通过";
END IF;

END $

#调用存储过程
CALL pass(1);

DELIMITER $
CREATE PROCEDURE pass1(IN i INT(10))
BEGIN

#if语句
IF i=0 THEN 
SELECT "不通过";
ELSEIF i=1 THEN
SELECT "通过";
ELSE
SELECT "你小子想干啥";
END IF;

END $

#调用存储过程
CALL pass1(2);


循环遍历

WHILE....DO...END WHILE

举例:

DELIMITER $

CREATE PROCEDURE pass8(IN num INT(10))
BEGIN

DECLARE i INT(100) DEFAULT 0;
WHILE i<=num DO
SET i=i+1;
END WHILE;

SELECT i;

END$

CALL pass8(5);


查看存储过程列表

SHOW PROCEDURE STATUS;


查看某个存储过程的结构和信息

show create procedure 存储过程名;

存储过程的删除

drop procedure  存储过程名;

以上是关于关于mysql 的存储过程的主要内容,如果未能解决你的问题,请参考以下文章

关于MySQL存储过程异常处理的一点心得

MySQL关于存储过程的简单Demo

sql中创建关于更新的存储过程

关于SQLSERVER存储过程的问题,求解

关于SQL创建存储过程的

关于存储过程返回游标的处理