Mysql 使用笔记

show tables; #查看数据库中的表,注意这外命令看不到临时表

rename table (db.oldtableName) to (db.newtableName)
#重命名数据库中的表(可以不带db.前缀),还可以把一个表从一个数据库,移到另外一个数据库,如 rename table a.old to b.old 这样就把old表从a库移动到了b库,前提是a和b两个在一个文件系统中。这个用法对临时表也无用,修改临时表的表名,必须用ALTER TABLE OLD_TP_TABLE_NAME RENAME NEW_TP_TABLE_NAME;
rename 可以同时对多个表进行改名操作,如:
rename table old1 to new1,
old2 to new2,
old3 to new3;
当您执行RENAME时,您不能有被锁定的表,也不能有处于活性状态的事务。您还必须拥有原表的ALTER和DROP权限,以及新表的CREATE和INSERT权限。

如果MySQL对多个表进行重命名时遇到了错误,MySQL会对所有已被重命名的表进行反向重命名,返回到原来的状态。

只要您不尝试通过重命名把视图加入另一个数据库中,则RENAME TABLE也可以用于视图。
--------------------------------
MySQL支持数个存储引擎作为对不同表的类型的处理器。MySQL存储引擎包括处理事务安全表的引擎和处理非事务安全表的引擎:
MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。MyISAM在所有MySQL配置里被支持,它是默认的存储引擎,除非你配置MySQL默认使用另外一个引擎。
InnoDB和BDB存储引擎提供事务安全表。BDB被包含在为支持它的操作系统发布的MySQL-Max二进制分发版里。InnoDB也默认被包括在所有MySQL 5.1二进制分发版里,你可以按照喜好通过配置MySQL来允许或禁止任一引擎。
NDB Cluster是被MySQL Cluster用来实现分割到多台计算机上的表的存储引擎。它在MySQL-Max 5.1二进制分发版里提供。这个存储引擎当前只被Linux, Solaris, 和Mac OS X 支持。在未来的MySQL分发版中,我们想要添加其它平台对这个引擎的支持,包括Windows。


-------------------------------------
desc a; 查看一个表结构

-------------------------------------
1、只有InnoDB支持事务;
2、我是想在存储过程里直接判断是否成功

执行成功是指SQL语句吧?即SQL语句没有问题还是执行SQL语句的结果?

前者:可以用捕获错误方法得到,
· Handler type (CONTINUE, EXIT)//处理类型,继续或退出
· Handler condition (SQLSTATE, MySQL error code, named condition) //触发条件
· Hander actions(错误触发的操作)
后者:ROW_COUNT()

-------------------------------------

测试了一下,在MYSQL中,
执行完SQL语句后,select @@error_count看看结果,这个值
是要随语句执行是否正确而改变的。
比如:
select * from t5;
T5不存在,则@@error_count=1
再执行
select * from t4;
T4存在,则@@error_count=0

----------------------------------------
很多资料中,对于事务的处理都很简单,抓捕SQL错误,仅仅是一个 @@error_count 吗? 肯定不是。@@error_count 只记录上一次SQL操作的结果,对于存储过程中多条语句肯定是不行的。

那么,怎么才能保证在存储过程中正确的回滚呢?让我们先来看个例子:

view plaincopy to clipboardprint?

1. CREATE TABLE `test` (`id` int(11) NOT NULL AUTO_INCREMENT,
2. `content` varchar(100), PRIMARY KEY (`id`) );
3.
4. DELIMITER $$
5. DROP PROCEDURE IF EXISTS test_sp1 $$
6. CREATE PROCEDURE test_sp1( )
7. BEGIN
8. START TRANSACTION;
9. INSERT INTO test VALUES(NULL, 'test sql 001'); /* 第一条 insert 能执行 */
10. INSERT INTO test VALUES('1', 'test sql 002'); /* 第二条 insert,不能执行 */
11.
12. IF @@error_count = 0 THEN
13. COMMIT;
14. ELSE
15. ROLLBACK;
16. END IF;
17.
18. END$$
19. DELIMITER ;

CREATE TABLE `test` (`id` int(11) NOT NULL AUTO_INCREMENT,
`content` varchar(100), PRIMARY KEY (`id`) );

DELIMITER $$
DROP PROCEDURE IF EXISTS test_sp1 $$
CREATE PROCEDURE test_sp1( )
BEGIN
START TRANSACTION;
INSERT INTO test VALUES(NULL, 'test sql 001'); /* 第一条 insert 能执行 */
INSERT INTO test VALUES('1', 'test sql 002'); /* 第二条 insert,不能执行 */

IF @@error_count = 0 THEN
COMMIT;
ELSE
ROLLBACK;
END IF;

END$$
DELIMITER ;

我们在MySQL客户端执行 CALL test_sp1(); 之后会发现,存储过程中第一条insert成功的执行了,而第二条执行没有执行,但是注意! 这里发生了错误,而作为判断的 @@error_count 没有反应, ROLLBACK 不能回滚!

在我上一篇文章 《执行一半的存储过程 - MySQL邯郸学步》中存储过程执行了一半, 而很不幸的,这里的 test_sp1() 也执行了一般,就好比我们PHP、JAVA、C++程序遇到错误一样,抛出error, 然后停止执行。

之前使用PDO,在处理事务时,使用SQLException捕获SQL错误,然后处理; 按照这个推论,我们必须在MySQL存储过程中捕获SQL错误,最后判断是回滚(ROLLBACK)还是提交(COMMIT)。 所以存储过程可以改为:
view plaincopy to clipboardprint?

1. DELIMITER $$
2. DROP PROCEDURE IF EXISTS test_sp1 $$
3. CREATE PROCEDURE test_sp1( )
4. BEGIN
5. DECLARE t_error INTEGER DEFAULT 0;
6. DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1;
7.
8. START TRANSACTION;
9. INSERT INTO test VALUES(NULL, 'test sql 001'); /* 第一条 insert 能执行 */
10. INSERT INTO test VALUES('1', 'test sql 002'); /* 第二条 insert,不能执行 */
11.
12. F txn_error = 1 THEN
13. ROLLBACK;
14. ELSE
15. COMMIT;
16. END IF;
17.
18. END$$
19. DELIMITER ;

DELIMITER $$
DROP PROCEDURE IF EXISTS test_sp1 $$
CREATE PROCEDURE test_sp1( )
BEGIN
DECLARE t_error INTEGER DEFAULT 0;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1;

START TRANSACTION;
INSERT INTO test VALUES(NULL, 'test sql 001'); /* 第一条 insert 能执行 */
INSERT INTO test VALUES('1', 'test sql 002'); /* 第二条 insert,不能执行 */

F txn_error = 1 THEN
ROLLBACK;
ELSE
COMMIT;
END IF;

END$$
DELIMITER ;

第二个例子中,我们为test_sp1() 定义了一个 SQLEXCEPTION 参数 t_error, 在遇到SQL错误时,继续执行(CONTINUE); 如果执行状态没有错误,则提交,反之回滚!
//-----------------------------------------------------------
DECLARE HANDLER syntax 声明异常处理的语法
DECLARE{ EXIT | CONTINUE }HANDLER FOR{ error-number | { SQLSTATE error-string } | condition }SQL statement  
上面就是错误处理的用法,也就是一段当程序出错后自动触发的代码。
MySQL允许两种处理器,一种是EXIT处理,我们刚才所用的就是这种。另一种就是我们将要演示的,CONTINUE处理,它跟EXIT处理类似,不同在于它执行后,原主程序仍然继续运行(而EXIT类型的Handler执行完for后面的语句后就会退出复合语句,即退出了原主程序),那么这个复合语句就没有出口了。


----------------------------------
mysql存储过程中
declare 定义变量一定要在
declare handler 或者是condition 之前。
例如:
create procedure test()
begin
declare a int default 0;
declare cur cursor for select * from test;
declare cur_flag int default 0;
declare continue handler for NOT FOUND set cur_flag =1;
.....
end;
上面的定义是对的。
下面的定义会报错
create procedure test()
begin
declare a int default 0;
declare cur cursor for select * from test;
declare continue handler for NOT FOUND set cur_flag =1; #这样是错误的,因为handler定义在变量cur_flag之前了。编译会报错,无法通过
declare cur_flag int default 0;
.....
end;
下面的定义也是错误的
create procedure test()
begin
declare continue handler for NOT FOUND set cur_flag =1; #这样是错误的,因为handler定义在变量a cur_flag之前了。编译会报错,无法通过。
#另外handler定义在cursor之前了,也会报错
declare a int default 0;
declare cur cursor for select * from test;
declare cur_flag int default 0;
.....
end;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值