成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

在測試MySQL腳本時所遇到的問題

開發 開發工具
MySQL作為一款廣受歡迎的開源數據庫,目前已被很多中小網站采用,在數據庫市場上占據了25%以上的市場份額。但是,如在本文中所描述的那樣,MySQL也并非是十全十美的。

近期,筆者在做MySQL腳本的移植和測試工作。在此過程中,發現了MySQL數據庫所存在的一些有待優化的地方,特寫下此文,供相關項目的開發人員參考。

一、存儲過程中所使用的參數名錯誤的問題

例如,在MySQL數據庫中新建如下表tb_testnum:

  1. drop table if exists tb_testnum; 
  2.  
  3. create table tb_testnum 
  4.     boxnumber         varchar(30)          not null
  5.     usertype          int                  not null                                                                                   
  6. ); 
  7. create unique index idx1_tb_testnum on tb_testnum(boxnumber); 

同時,創建如下存儲過程pr_dealtestnum:

  1. drop procedure if exists pr_dealtestnum; 
  2. delimiter // 
  3.  
  4. create procedure pr_dealtestnum 
  5.     in    p_boxnumber    varchar(30) 
  6. pr_dealtestnum_label:begin 
  7.     declare   p_boxnumcount    int
  8.  
  9.     select count(*) into p_boxnumcount from tb_testnum where boxnumber=p_boxnumbe; 
  10.  
  11.     select p_boxnumcount; 
  12.  
  13.     leave pr_dealtestnum_label; 
  14. end
  15. // 
  16. delimiter ; 
  17. 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數據庫居然不報錯:

  1. > mysql -uroot -p'root' -h10.10.10.10 -P3306 -Ddbtest<pr_dealtestnum.sql 
  2. create procedure pr_dealtestnum ok 
  3. create procedure pr_dealtestnum ok 

接著,在MySQL數據庫上調用該存儲過程時報錯,提示“p_boxnumbe”不存在:

  1. mysql> call pr_dealtestnum('2344273522'); 
  2. ERROR 1054 (42S22): Unknown column 'p_boxnumbe' in 'where clause' 

這樣,問題就出現了,難道MySQL數據庫對存儲過程中所使用的參數名的檢查不嚴格?

二、存儲過程中所使用的參數名前面存在多余符號的問題

這個問題和***個問題類似,只是“參數名錯誤”變成了“在參數名前面有多余的符號”。

例如,我們還是使用問題一中的表tb_testnum,并在表中插入數據:

  1. insert into tb_testnum(boxnumber,usertype) values('2344273522',1);11 

同時,創建如下存儲過程pr_dealtestnum:

  1. drop procedure if exists pr_dealtestnum; 
  2. delimiter // 
  3.  
  4. create procedure pr_dealtestnum 
  5.     in    p_boxnumber    varchar(30) 
  6. pr_dealtestnum_label:begin 
  7.     declare   p_boxnumcount    int
  8.  
  9.     select count(*) into p_boxnumcount from tb_testnum where boxnumber=@p_boxnumber; 
  10.  
  11.     select p_boxnumcount; 
  12.  
  13.     leave pr_dealtestnum_label; 
  14. end
  15. // 
  16. delimiter ; 
  17. 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數據庫居然不報錯:

  1. > mysql -uroot -p'root' -h10.10.10.10 -P3306 -Ddbtest<pr_dealtestnum.sql  
  2. create procedure pr_dealtestnum ok  
  3. create procedure pr_dealtestnum ok123123 

接著,在MySQL數據庫上調用該存儲過程時無報錯,但是輸出的結果不正確:

  1. mysql> call pr_dealtestnum('2344273522'); 
  2. +---------------+ 
  3. | p_boxnumcount | 
  4. +---------------+ 
  5. |             0 | 
  6. +---------------+ 
  7. 1 row in set (0.00 sec) 
  8.  
  9. 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數據庫會報錯:

  1. mysql> insert into tb_testnum(boxnumber,usertype) values('2344273523',1,1); 
  2. ERROR 1136 (21S01): Column count doesn't match value count at row 1 

報錯的原因是表tb_testnum只有兩列,但是欲向其中插入三列數據。

接著,創建如下存儲過程pr_dealtestnum:

  1. drop procedure if exists pr_dealtestnum; 
  2. delimiter // 
  3.  
  4. create procedure pr_dealtestnum 
  5.     in    p_boxnumber    varchar(30), 
  6.     in    p_usertype     int 
  7. pr_dealtestnum_label:begin 
  8.  
  9.     insert into tb_testnum(boxnumber,usertype) values(p_boxnumber,p_usertype,1); 
  10.  
  11.     leave pr_dealtestnum_label; 
  12. end
  13. // 
  14. delimiter ; 
  15. select 'create procedure pr_dealtestnum ok'

注意,“insert into tb_testnum(boxnumber,usertype) values(p_boxnumber,p_usertype,1);”語句中表的列數和插入數據的列數不一致。

將存儲過程pr_dealtestnum放到pr_dealtestnum.sql文件中,使用命令行運行該腳本文件,發現MySQL數據庫居然不報錯:

  1. > mysql -uroot -p'root' -h10.10.10.10 -P3306 -Ddbtest<pr_dealtestnum.sql 
  2. create procedure pr_dealtestnum ok 
  3. create procedure pr_dealtestnum ok 

然后,在MySQL數據庫上調用該存儲過程時報錯,提示列不匹配:

  1. mysql> call pr_dealtestnum('2344273523',1);  
  2. ERROR 1136 (21S01): Column count doesn't match value count at row 11212 

這樣,又一個問題出現了,難道MySQL數據庫對存儲過程中的數據插入語句不判斷前后列數是否匹配?

四、存儲過程中的select語句的編寫問題

例如,我們還是使用前面的表tb_testnum,并創建如下存儲過程pr_dealtestnum:

  1. drop procedure if exists pr_dealtestnum; 
  2. delimiter // 
  3.  
  4. create procedure pr_dealtestnum 
  5.     in    p_boxnumber    varchar(30) 
  6. pr_dealtestnum_label:begin 
  7.     declare   p_boxnumcount    int
  8.  
  9.     select p_boxnumcount=count(*) from tb_testnum where boxnumber=p_boxnumber; 
  10.  
  11.     select p_boxnumcount; 
  12.  
  13.     leave pr_dealtestnum_label; 
  14. end
  15. // 
  16. delimiter ; 
  17. 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數據庫居然不報錯:

  1. > mysql -uroot -p'root' -h10.10.10.10 -P3306 -Ddbtest<pr_dealtestnum.sql  
  2. create procedure pr_dealtestnum ok  
  3. create procedure pr_dealtestnum ok123123 

然后,在MySQL數據庫上調用該存儲過程,輸出結果如下:

  1. mysql> call pr_dealtestnum('2344273522'); 
  2. +------------------------+ 
  3. | p_boxnumcount=count(*) | 
  4. +------------------------+ 
  5. |                   NULL | 
  6. +------------------------+ 
  7. 1 row in set (0.00 sec) 
  8.  
  9. +---------------+ 
  10. | p_boxnumcount | 
  11. +---------------+ 
  12. |          NULL | 
  13. +---------------+ 
  14. 1 row in set (0.00 sec) 
  15.  
  16. Query OK, 0 rows affected (0.00 sec) 

以上結果與我們預期的結果相差甚遠。

這樣,又一個問題出現了,難道MySQL數據庫對存儲過程中的每條語句不作嚴格的語法校驗?

五、存儲過程中取整數值的問題

例如,我們創建如下存儲過程pr_calculate:

  1. drop procedure if exists pr_calculate; 
  2. delimiter // 
  3.  
  4. create procedure pr_calculate 
  5.     in    p_intnum1    int
  6.     in    p_intnum2    int 
  7. pr_calculate_label:begin 
  8.     declare   p_result    int
  9.  
  10.     set p_result = (p_intnum1+p_intnum2)/10*10; 
  11.  
  12.     select p_result; 
  13.  
  14.     leave pr_calculate_label; 
  15. end
  16. // 
  17. delimiter ; 
  18. select 'create procedure pr_calculate ok'

在此存儲過程中,我們想把“(p_intnum1+p_intnum2)/10*10”結果賦給整型變量p_result。

將存儲過程pr_calculate放到pr_calculate.sql文件中,使用命令行運行該腳本文件,結果如下:

  1. > mysql -uroot -p'root' -h10.10.10.10 -P3306 -Ddbtest<pr_calculate.sql  
  2. create procedure pr_calculate ok  
  3. create procedure pr_calculate ok123123 

然后,在MySQL數據庫上調用該存儲過程,輸出結果如下:

  1. mysql> call pr_calculate(2,1); 
  2. +----------+ 
  3. | p_result | 
  4. +----------+ 
  5. |        3 | 
  6. +----------+ 
  7. 1 row in set (0.00 sec) 
  8.  
  9. Query OK, 0 rows affected (0.00 sec) 
  10.  
  11. mysql> call pr_calculate(2,3); 
  12. +----------+ 
  13. | p_result | 
  14. +----------+ 
  15. |        5 | 
  16. +----------+ 
  17. 1 row in set (0.00 sec) 
  18.  
  19. Query OK, 0 rows affected (0.00 sec) 
  20.  
  21. mysql> call pr_calculate(2,6); 
  22. +----------+ 
  23. | p_result | 
  24. +----------+ 
  25. |        8 | 
  26. +----------+ 
  27. 1 row in set (0.00 sec) 
  28.  
  29. Query OK, 0 rows affected (0.00 sec) 
  30.  
  31. mysql> call pr_calculate(2,9); 
  32. +----------+ 
  33. | p_result | 
  34. +----------+ 
  35. |       11 | 
  36. +----------+ 
  37. 1 row in set (0.00 sec) 
  38.  
  39. Query OK, 0 rows affected (0.00 sec) 
  40.  
  41. mysql> call pr_calculate(2,8); 
  42. +----------+ 
  43. | p_result | 
  44. +----------+ 
  45. |       10 | 
  46. +----------+ 
  47. 1 row in set (0.00 sec) 
  48.  
  49. Query OK, 0 rows affected (0.00 sec) 
  50.  
  51. mysql> call pr_calculate(3,13); 
  52. +----------+ 
  53. | p_result | 
  54. +----------+ 
  55. |       16 | 
  56. +----------+ 
  57. 1 row in set (0.00 sec) 
  58.  
  59. 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數據庫上執行如下語句:

  1. mysql> select convert(8/6, signed); 
  2. +----------------------+ 
  3. convert(8/6, signed) | 
  4. +----------------------+ 
  5. |                    1 | 
  6. +----------------------+ 
  7. 1 row in set (0.00 sec) 
  8.  
  9. mysql> select convert(9/6, signed); 
  10. +----------------------+ 
  11. convert(9/6, signed) | 
  12. +----------------------+ 
  13. |                    2 | 
  14. +----------------------+ 
  15. 1 row in set (0.00 sec) 

可以看到,因為“8/6”小于1.5,所以對其取整后的值就為1;而因為“9/6”等于1.5,所以對其取整后的值就為2。這也可以看出,在將小數轉換為整數的過程中,MySQL數據庫遵循的是“四舍五入”的原則。

七、總結

MySQL作為一款廣受歡迎的開源數據庫,目前已被很多中小網站采用,在數據庫市場上占據了25%以上的市場份額。但是,如在本文中所描述的那樣,MySQL也并非是十全十美的。

期待MySQL會不斷進行優化,讓更多的軟件產品來使用它。

【本文是51CTO專欄作者周兆熊的原創文章,作者微信公眾號:周氏邏輯(logiczhou)】

責任編輯:武曉燕 來源: csdn博客
相關推薦

2012-05-17 15:15:11

Linux

2009-07-07 13:12:44

Java Servle

2011-04-01 16:04:03

zabbixconfigure

2011-04-01 16:04:58

zabbixconfigure

2010-08-06 08:50:21

ASP.NET

2024-04-01 07:53:51

MySQL索引字符

2011-07-18 16:33:20

sqlite

2023-06-25 08:05:09

MySQL事務并發

2011-07-08 10:28:49

布線系統測試

2009-12-18 16:57:23

ADSL寬帶路由器上網

2010-09-17 13:03:47

2010-05-13 17:33:24

MySQL索引

2020-03-03 09:28:30

Python內存開發

2024-01-09 15:37:46

2022-06-20 16:18:25

MySQL安全免密碼輸入

2012-05-27 18:24:12

蘋果

2020-07-22 08:08:35

MavenIDEA版本

2019-04-22 12:25:40

UbuntuLinux IP地址

2010-10-13 10:34:49

MySQL修改表結構

2021-10-12 00:04:24

腳本備份MariDB
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲性在线 | av天天澡天天爽天天av | 精品无码久久久久国产 | 欧美性成人 | yiren22综合网成人 | 精品啪啪 | 欧美激情一区二区 | 久久亚洲春色中文字幕久久久 | 日本啊v在线 | 亚洲精品国产电影 | 亚洲一二三区精品 | 亚洲逼院 | 91精品国产91久久久久久最新 | 成人免费网视频 | 99热最新 | 一级黄色生活视频 | 一区二区成人 | 免费观看一区二区三区毛片 | 男女视频在线观看 | 国产精品片aa在线观看 | 日韩免费看视频 | 五月槐花香 | 国产欧美一区二区三区另类精品 | 老司机免费视频 | 一区二区三区在线 | 婷婷色在线 | 日日日干干干 | 女女百合av大片一区二区三区九县 | 黄色免费观看网站 | 一区二区三区在线电影 | 综合一区| 国产精品久久久久久久7777 | 老牛嫩草一区二区三区av | 成人av电影免费在线观看 | 一二三四在线视频观看社区 | 欧洲视频一区二区 | 岛国精品 | 一级欧美黄色片 | 亚洲欧美网 | 亚洲看片 | 91精品国产一区二区三区蜜臀 |