在测试MySQL脚本时所遇到的问题
来源:互联网 发布:mac口红官网价格多少 编辑:程序博客网 时间:2024/06/05 07:28
近期,笔者在做MySQL脚本的移植和测试工作。在此过程中,发现了MySQL数据库所存在的一些有待优化的地方,特写下此文,供相关项目的开发人员参考。
一、存储过程中所使用的参数名错误的问题
例如,在MySQL数据库中新建如下表tb_testnum:
drop table if exists tb_testnum;create table tb_testnum( boxnumber varchar(30) not null, usertype int not null );create unique index idx1_tb_testnum on tb_testnum(boxnumber);
同时,创建如下存储过程pr_dealtestnum:
drop procedure if exists pr_dealtestnum;delimiter //create procedure pr_dealtestnum( in p_boxnumber varchar(30))pr_dealtestnum_label:begin declare p_boxnumcount int; select count(*) into p_boxnumcount from tb_testnum where boxnumber=p_boxnumbe; select p_boxnumcount; leave pr_dealtestnum_label;end;//delimiter ;select 'create procedure pr_dealtestnum ok';
注意,“select count(*) into p_boxnumcount from tb_testnum where boxnumber=p_boxnumbe;”语句中的参数“p_boxnumbe”与输入参数“p_boxnumber”不一样(少了一个r),该参数未在存储过程中定义。
将存储过程pr_dealtestnum放到pr_dealtestnum.sql文件中,使用命令行运行该脚本文件,发现MySQL数据库居然不报错:
> mysql -uroot -p'root' -h10.10.10.10 -P3306 -Ddbtest<pr_dealtestnum.sqlcreate procedure pr_dealtestnum okcreate procedure pr_dealtestnum ok
接着,在MySQL数据库上调用该存储过程时报错,提示“p_boxnumbe”不存在:
mysql> call pr_dealtestnum('2344273522');ERROR 1054 (42S22): Unknown column 'p_boxnumbe' in 'where clause'
这样,问题就出现了,难道MySQL数据库对存储过程中所使用的参数名的检查不严格?
二、存储过程中所使用的参数名前面存在多余符号的问题
这个问题和第一个问题类似,只是“参数名错误”变成了“在参数名前面有多余的符号”。
例如,我们还是使用问题一中的表tb_testnum,并在表中插入数据:
insert into tb_testnum(boxnumber,usertype) values('2344273522',1);
同时,创建如下存储过程pr_dealtestnum:
drop procedure if exists pr_dealtestnum;delimiter //create procedure pr_dealtestnum( in p_boxnumber varchar(30))pr_dealtestnum_label:begin declare p_boxnumcount int; select count(*) into p_boxnumcount from tb_testnum where boxnumber=@p_boxnumber; select p_boxnumcount; leave pr_dealtestnum_label;end;//delimiter ;select 'create procedure pr_dealtestnum ok';
注意,“select count(*) into p_boxnumcount from tb_testnum where boxnumber=@p_boxnumber;”语句中的参数“@p_boxnumber”是在输入参数“p_boxnumber”的前面添加了@符号。
将存储过程pr_dealtestnum放到pr_dealtestnum.sql文件中,使用命令行运行该脚本文件,发现MySQL数据库居然不报错:
> mysql -uroot -p'root' -h10.10.10.10 -P3306 -Ddbtest<pr_dealtestnum.sqlcreate procedure pr_dealtestnum okcreate procedure pr_dealtestnum ok
接着,在MySQL数据库上调用该存储过程时无报错,但是输出的结果不正确:
mysql> call pr_dealtestnum('2344273522');+---------------+| p_boxnumcount |+---------------+| 0 |+---------------+1 row in set (0.00 sec)Query OK, 0 rows affected (0.00 sec)
因为我们在前面已经向表tb_testnum中插入了一条数据,所以正确的输出应该是1,而不是0。
我们将“select count(*) into p_boxnumcount from tb_testnum where boxnumber=@p_boxnumber;”语句中的“@p_boxnumber”中的@符号去掉,再放到MySQL数据库中运行,发现执行“call pr_dealtestnum(‘2344273522’);”之后输出的结果就是正确的了。
这也说明了MySQL数据库对存储过程中所使用的参数名的检查不严格。
三、存储过程中向表中插入多余数据的问题
例如,我们还是使用前面两个问题中的表tb_testnum,如果直接向表中插入多余的数据,则MySQL数据库会报错:
mysql> insert into tb_testnum(boxnumber,usertype) values('2344273523',1,1);ERROR 1136 (21S01): Column count doesn't match value count at row 1
报错的原因是表tb_testnum只有两列,但是欲向其中插入三列数据。
接着,创建如下存储过程pr_dealtestnum:
drop procedure if exists pr_dealtestnum;delimiter //create procedure pr_dealtestnum( in p_boxnumber varchar(30), in p_usertype int)pr_dealtestnum_label:begin insert into tb_testnum(boxnumber,usertype) values(p_boxnumber,p_usertype,1); leave pr_dealtestnum_label;end;//delimiter ;select 'create procedure pr_dealtestnum ok';
注意,“insert into tb_testnum(boxnumber,usertype) values(p_boxnumber,p_usertype,1);”语句中表的列数和插入数据的列数不一致。
将存储过程pr_dealtestnum放到pr_dealtestnum.sql文件中,使用命令行运行该脚本文件,发现MySQL数据库居然不报错:
> mysql -uroot -p'root' -h10.10.10.10 -P3306 -Ddbtest<pr_dealtestnum.sqlcreate procedure pr_dealtestnum okcreate procedure pr_dealtestnum ok
然后,在MySQL数据库上调用该存储过程时报错,提示列不匹配:
mysql> call pr_dealtestnum('2344273523',1); ERROR 1136 (21S01): Column count doesn't match value count at row 1
这样,又一个问题出现了,难道MySQL数据库对存储过程中的数据插入语句不判断前后列数是否匹配?
四、存储过程中的select语句的编写问题
例如,我们还是使用前面的表tb_testnum,并创建如下存储过程pr_dealtestnum:
drop procedure if exists pr_dealtestnum;delimiter //create procedure pr_dealtestnum( in p_boxnumber varchar(30))pr_dealtestnum_label:begin declare p_boxnumcount int; select p_boxnumcount=count(*) from tb_testnum where boxnumber=p_boxnumber; select p_boxnumcount; leave pr_dealtestnum_label;end;//delimiter ;select 'create procedure pr_dealtestnum ok';
注意,“select p_boxnumcount=count() from tb_testnum where boxnumber=p_boxnumber;”语句是不符合MySQL语法规则的,正确的语句应该是“select count() into p_boxnumcount from tb_testnum where boxnumber=@p_boxnumber;”。
将存储过程pr_dealtestnum放到pr_dealtestnum.sql文件中,使用命令行运行该脚本文件,发现MySQL数据库居然不报错:
> mysql -uroot -p'root' -h10.10.10.10 -P3306 -Ddbtest<pr_dealtestnum.sqlcreate procedure pr_dealtestnum okcreate procedure pr_dealtestnum ok
然后,在MySQL数据库上调用该存储过程,输出结果如下:
mysql> call pr_dealtestnum('2344273522');+------------------------+| p_boxnumcount=count(*) |+------------------------+| NULL |+------------------------+1 row in set (0.00 sec)+---------------+| p_boxnumcount |+---------------+| NULL |+---------------+1 row in set (0.00 sec)Query OK, 0 rows affected (0.00 sec)
以上结果与我们预期的结果相差甚远。
这样,又一个问题出现了,难道MySQL数据库对存储过程中的每条语句不作严格的语法校验?
五、存储过程中取整数值的问题
例如,我们创建如下存储过程pr_calculate:
drop procedure if exists pr_calculate;delimiter //create procedure pr_calculate( in p_intnum1 int, in p_intnum2 int)pr_calculate_label:begin declare p_result int; set p_result = (p_intnum1+p_intnum2)/10*10; select p_result; leave pr_calculate_label;end;//delimiter ;select 'create procedure pr_calculate ok';
在此存储过程中,我们想把“(p_intnum1+p_intnum2)/10*10”结果赋给整型变量p_result。
将存储过程pr_calculate放到pr_calculate.sql文件中,使用命令行运行该脚本文件,结果如下:
> mysql -uroot -p'root' -h10.10.10.10 -P3306 -Ddbtest<pr_calculate.sqlcreate procedure pr_calculate okcreate procedure pr_calculate ok
然后,在MySQL数据库上调用该存储过程,输出结果如下:
mysql> call pr_calculate(2,1);+----------+| p_result |+----------+| 3 |+----------+1 row in set (0.00 sec)Query OK, 0 rows affected (0.00 sec)mysql> call pr_calculate(2,3);+----------+| p_result |+----------+| 5 |+----------+1 row in set (0.00 sec)Query OK, 0 rows affected (0.00 sec)mysql> call pr_calculate(2,6);+----------+| p_result |+----------+| 8 |+----------+1 row in set (0.00 sec)Query OK, 0 rows affected (0.00 sec)mysql> call pr_calculate(2,9);+----------+| p_result |+----------+| 11 |+----------+1 row in set (0.00 sec)Query OK, 0 rows affected (0.00 sec)mysql> call pr_calculate(2,8);+----------+| p_result |+----------+| 10 |+----------+1 row in set (0.00 sec)Query OK, 0 rows affected (0.00 sec)mysql> call pr_calculate(3,13);+----------+| p_result |+----------+| 16 |+----------+1 row in set (0.00 sec)Query OK, 0 rows affected (0.00 sec)
以上输出结果与我们的预期不相符,如对于“call pr_calculate(2,9);”,参数传进去之后,表达式的值为“set p_result = (2+9)/10*10;”,按照以往的经验,“(2+9)/10*10”的结果应该为10,即“(2+9)/10”应该为1,但是在MySQL中,该表达式的值却为11。
这说明了在MySQL数据库中,对于整型变量的计算规则有所不同。
六、“四舍五入”的问题
例如,直接在MySQL数据库上执行如下语句:
mysql> select convert(8/6, signed);+----------------------+| convert(8/6, signed) |+----------------------+| 1 |+----------------------+1 row in set (0.00 sec)mysql> select convert(9/6, signed);+----------------------+| convert(9/6, signed) |+----------------------+| 2 |+----------------------+1 row in set (0.00 sec)
可以看到,因为“8/6”小于1.5,所以对其取整后的值就为1;而因为“9/6”等于1.5,所以对其取整后的值就为2。这也可以看出,在将小数转换为整数的过程中,MySQL数据库遵循的是“四舍五入”的原则。
七、总结
MySQL作为一款广受欢迎的开源数据库,目前已被很多中小网站采用,在数据库市场上占据了25%以上的市场份额。但是,如在本文中所描述的那样,MySQL也并非是十全十美的。
期待MySQL会不断进行优化,让更多的软件产品来使用它。
- 在测试MySQL脚本时所遇到的问题
- 手机自动化测试所遇到的问题
- MySQL入门学习时,所遇到的问题(1)
- 安装mysql集群所遇到的问题
- MySQL卸载重装所遇到的问题
- PDO在连接数据库时所可能遇到的问题
- 我在qemu所遇到的问题
- 自动化测试时遇到的脚本录制问题及解决方法
- 在JAVA向Mysql的数据库中插入数据过大所遇到的问题
- 执行MySQL脚本文件遇到的问题
- 测试连接MySQL数据库时遇到的一些问题
- 文件上传时,所遇到的问题
- mysql远程登录,所遇到的问题及解决方案
- oracle语句转mysql语句所遇到的问题
- 在treegrid方法添加checkbox所遇到的问题。
- 在MONO下实现WCF所遇到的问题
- Ruby在windows下配置所遇到的问题
- 在centos7上配置caffe所遇到的一些问题
- 过 DNF TP 驱动保护(一)
- oracle中的decode的使用
- PAT:1082. Read Number in Chinese (25)
- 正向代理与反向代理的区别【Nginx读书笔记】
- android 机顶盒 listview 获取焦点改变item背景
- 在测试MySQL脚本时所遇到的问题
- java关键字this、super的用法
- C++ 用函数 泰勒公式求 sinx 的 cosx 值
- 过 DNF TP 驱动保护(二)
- 51nod1685:第K大区间2
- 通过日期获取年龄 extjs
- 关于Fragment的方方面面
- 基因数据处理46之cloud-scale-bwamem安装(compile.pl安装没问题)
- Netbeans学习总结