存储过程中如何提前返回?

madmanahong 2010-12-17 10:46:48
存储过程中如何提前返回?

因为我没有看到类似GOTO的语句,但是有个LEAVE,好像LEAVE是离开一个标号。他能提前返回存储过程吗?

譬如:

BEGIN


SELECT * FROM ..
IF ROW_COUNT() = 1 THEN
LEAVE;


END IF;

END

这样有什么影响?





=======================================================

第2个问题,存储过程不提交会不会自动回滚?这样写有什么问题?
存储过程用手动COMMIT吗?



BEGIN

INSERT ....

SELECT * FROM ..
IF ROW_COUNT() = 1 THEN
# 出错了,那么刚才那个INSERT会不会自动回滚?
# 注意这个存储过程不是在一个事务中。
END IF;

#这里是否需要手动COMMIT;
COMMIT;
END


3)这个问题有点诡异


BEGIN
#如果设置了
SET AUTOCOMMIT = 0;

#但是退出的时候没有COMMIT,也没有设置AUTOCOMMIT;会有什么问题?
# mysql会自动恢复AUTOCOMMIT吗?


END



4) 事务有头无尾怎么办?

BEGIN
START TRANSACTION;

# do something

# 离开的时候我没有调用COMMIT;那么数据便没有写入
# 那么如果我也没有调用ROLLBACK;数据也会自动回滚吧??!!


# 那么此时我再调用START TRANSACTION + COMMIT;会不会连第一次的数据也会写入,因为第一次我并没有调用ROLLBACK?
# 如果我在另外的存储过程中调用START TRANSACTION + COMMIT;又会有什么不一样的情况?、
# 是不是离开存储过程的时候,会自动结束当前事务???
END




非常感谢!



...全文
498 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
ACMAIN_CHM 2010-12-17
  • 打赏
  • 举报
回复
[Quote]1。更新
2。删除
3。插入


如果在第3条语句中出错。那么我跳出了这个储存过程,第1,2条是否会回滚?


如果这三条语句的顺序颠倒一下

1。插入
2。更新
3。删除

我在第2条语句中提前返回,第1条语句的会不会回滚?
理论上应该不会吧。。除非这是在一个事务中。
我的理解对吗?[/Quote]

这个时候autocommit是什么?
madmanahong 2010-12-17
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 acmain_chm 的回复:]
引用第2个问题,存储过程不提交会不会自动回滚?这样写有什么问题?
存储过程用手动COMMIT吗?



BEGIN
INSERT ....
SELECT * FROM ..
IF ROW_COUNT() = 1 THEN
# 出错了,那么刚才那个INSERT会不会自动回滚?
# 注意这个存储过程不是在一个事务中。
END IF;

#这里是否需要手动COMMIT;
CO……
[/Quote]



第2个问题是我在一个存储过程中有3个语句。但这个存储过程并不是事务。



1。更新
2。删除
3。插入


如果在第3条语句中出错。那么我跳出了这个储存过程,第1,2条是否会回滚?


如果这三条语句的顺序颠倒一下

1。插入
2。更新
3。删除

我在第2条语句中提前返回,第1条语句的会不会回滚?
理论上应该不会吧。。除非这是在一个事务中。
我的理解对吗?



=======================================
的确可以自己试验,但是有的时候眼见不一定为实。
因为测试环境可能搭的不好,或者搭的有错误,从而相信了自己看到的错误答案,这情况我想做技术的应该会看到。

所以我还是想在理论上站住脚。而且我本人也么有那么大的精力去翻看source。
所以只能请教这里有经验的高人了。。








小小小小周 2010-12-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 acmain_chm 的回复:]
label1: BEGIN
SELECT * FROM ..
IF ROW_COUNT() = 1 THEN
LEAVE label1;
END IF;
END
[/Quote]
学习到了,还以为 LEAVE只是LOOP循环的离开标号;

事务不提交不会自动回滚,需要给他标记一个commit或则rollback;
设置SET AUTOCOMMIT = 0;退出的时候没有COMMIT,也没有设置AUTOCOMMIT;会阻碍其他session 修改该事务中的表;需要自己设置autocommit=1;
事务的提交和回滚在autocommit=0的前提下,都需要自己手动的commit和rollback才可以;
WWWWA 2010-12-17
  • 打赏
  • 举报
回复
1、加入LABEL
LABEL: BEGIN
SELECT * FROM WHERE ..
IF ROW_COUNT() = 1 THEN
LEAVE label1;
END IF;
END
2、
没有提交就没有回滚

3、
没有提交,估计修改没有存入,可以测试一下,一般要 COMMIT才会提交
4、测试一下就知道了,
ACMAIN_CHM 2010-12-17
  • 打赏
  • 举报
回复
[Quote]3)这个问题有点诡异


BEGIN
#如果设置了
SET AUTOCOMMIT = 0;

#但是退出的时候没有COMMIT,也没有设置AUTOCOMMIT;会有什么问题?
# mysql会自动恢复AUTOCOMMIT吗?


END
[/Quote]事务尚未提交。 mysql不会自动恢复AUTOCOMMIT吗?
建议试验一下。


[Quote]。[/Quote]
BEGIN
START TRANSACTION;

# do something

# 离开的时候我没有调用COMMIT;那么数据便没有写入
没有写入
# 那么如果我也没有调用ROLLBACK;数据也会自动回滚吧??!!
不会自动回滚

# 那么此时我再调用START TRANSACTION + COMMIT;会不会连第一次的数据也会写入,因为第一次我并没有调用ROLLBACK?
START TRANSACTION会提交上个事务。

# 如果我在另外的存储过程中调用START TRANSACTION + COMMIT;又会有什么不一样的情况?、
举例说明,无法假设
# 是不是离开存储过程的时候,会自动结束当前事务???
不会
END


以上问题其实都可以自己设计试验进行测试。理论联系实践并检验理论。
ACMAIN_CHM 2010-12-17
  • 打赏
  • 举报
回复
[Quote]第2个问题,存储过程不提交会不会自动回滚?这样写有什么问题?
存储过程用手动COMMIT吗?



BEGIN
INSERT ....
SELECT * FROM ..
IF ROW_COUNT() = 1 THEN
# 出错了,那么刚才那个INSERT会不会自动回滚?
# 注意这个存储过程不是在一个事务中。
END IF;

#这里是否需要手动COMMIT;
COMMIT;
END[/Quote]

这个问题没看懂你的环境。“存储过程不是在一个事务中 是指什么?理论上INNODB任何一个操作都会是事务,如果AUTOCOMMIT=1,则每句后会自动提交事务。如果AUTOCOMMIT=0则,需要自己提交或隐式提交。
ACMAIN_CHM 2010-12-17
  • 打赏
  • 举报
回复
[Quote]存储过程中如何提前返回?

因为我没有看到类似GOTO的语句,但是有个LEAVE,好像LEAVE是离开一个标号。他能提前返回存储过程吗?

譬如:

BEGIN


SELECT * FROM ..
IF ROW_COUNT() = 1 THEN
LEAVE;


END IF;

END

这样有什么影响?

[/Quote]

label1: BEGIN
SELECT * FROM ..
IF ROW_COUNT() = 1 THEN
LEAVE label1;
END IF;
END

ACMAIN_CHM 2010-12-17
  • 打赏
  • 举报
回复
[Quote]autocommit = 1[/Quote]
[Quote]引用1。更新
2。删除
3。插入


如果在第3条语句中出错。那么我跳出了这个储存过程,第1,2条是否会回滚?[/Quote]跳出了这个储存过程

[Quote]如果这三条语句的顺序颠倒一下

1。插入
2。更新
3。删除

我在第2条语句中提前返回,第1条语句的会不会回滚?[/Quote]不会


[Quote]理论上应该不会吧。。除非这是在一个事务中。
我的理解对吗?[/Quote]因为每一句都是单独的一个事务。MYSQL已经自动提交了。
madmanahong 2010-12-17
  • 打赏
  • 举报
回复
autocommit = 1

56,687

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧