日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql游标遍历中sql语句出现异常_MySQL中的异常处理,游标

發布時間:2024/7/23 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql游标遍历中sql语句出现异常_MySQL中的异常处理,游标 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、異常處理的理解

ERROR 1062 (23000): Duplicate entry ‘2’ for key ‘PRIMARY’

錯誤 4位error code(5位sql statis):錯誤內容

二、異常處理的重要性

沒有異常處理的存儲過程,執行過程中非常難以預測執行結果。

建議:存儲過程中加上異常處理部分。

三、異常處理的實現

異常處理的格式:

DECLARECONTINUE/EXITHANDLER FORSQLSTATE ‘23000’ (錯誤代碼)

1.錯誤是什么?

eg:1062(23000)

2.怎么處理錯誤?

先執行SQL,再執行EXIT/CONTINUE

小結:

針對什么錯誤,首先執行SQL語句,可以是一個begin..end;語句塊;

根據是continue還是exit,確定是接著執行還是退出begin..end;

接著執行的話,就是接著執行出錯的SQL的下一條語句;

如果是退出,就退出這個declare所在的begin…end。

例子1:

DELIMITER $$

CREATE PROCEDURE small_mistake1(

OUT error VARCHAR(5))

BEGIN

DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' --》這是個異常

SET error = '23000'; //用來記錄錯誤發生時的一些信息,異常捕獲、處理

select error;

SET error = '00000';

select error;

INSERT INTO TEAMS VALUES(2,27,'third');

SET error = '23001';

END$$

DELIMITER ;

執行結果:

mysql> call small_mistake1(@a); --》上來直接就是select error,因為先執行sql

+-------+

| error |

+-------+

| NULL |

+-------+

1 row in set (0.00 sec)

+-------+

| error |

+-------+

| 00000 |

+-------+

1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> select @a; --》

+-------+

| @a |

+-------+

| 23001 |

+-------+

1 row in set (0.00 sec)

===例子2:

CREATE TABLE test.t (s1 INT, PRIMARY KEY (s1));

delimiter $$

CREATE PROCEDURE handlerdemo ()

BEGIN

DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;

SET @x = 1;

INSERT INTO test.t VALUES (1); ---》能執行

SET @x = 2; --》報錯,因為@x==1

INSERT INTO test.t VALUES (1);

SET @x = 3;

END$$

delimiter ;

CALL handlerdemo()

執行結果:

mysql> select @x2; --》捕獲到異常,就令x2=1

+------+

| @x2 |

+------+

| 1 |

+------+

1 row in set (0.00 sec)

mysql> select @x; --》set @x=3

+------+

| @x |

+------+

| 3 |

+------+

1 row in set (0.00 sec)

===例子3:

DELIMITER $$

CREATE PROCEDURE small_mistake2(

OUT error VARCHAR(5))

BEGIN

DECLARE EXIT HANDLER FOR SQLSTATE '23000' --》EXIT直接退出begin..end

SET error = '23000';

select error;

SET error = '00000';

select error;

INSERT INTO TEAMS VALUES(2,27,'third');

--》此語句出錯,捕獲到異常后,因為是exit,所以不會再執行下面的set error='23001'語句

SET error = '23001';

END$$

DELIMITER ;

mysql> call small_mistake2(@a); --》先執行sql

+-------+

| error |

+-------+

| NULL |

+-------+

1 row in set (0.00 sec) --》捕獲到異常

+-------+

| error |

+-------+

| 00000 |

+-------+

1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> select @a; ---》證明沒有執行set error='23001'

+-------+

| @a |

+-------+

| 23000 |

+-------+

1 row in set (0.00 sec)

===例子4:一個begin后面可以接多個DECLARE

DELIMITER $$

CREATE PROCEDURE small_mistake3(

OUT error VARCHAR(5))

BEGIN

DECLARE CONTINUE HANDLER FOR SQLSTATE '23000'

SET error = '23000';

DECLARE CONTINUE HANDLER FOR SQLSTATE '21S01'

SET error = '21S01';

INSERT INTO TEAMS VALUES(2,27,'third',5);

END$$

DELIMITER ;

mysql> call small_mistake3(@error);

Query OK, 0 rows affected (0.00 sec)

mysql> select @error;

+--------+

| @error |

+--------+

| 21S01 |

+--------+

1 row in set (0.00 sec)

四、錯誤捕獲快捷方式

異常處理的好處:

①出錯不報錯

②出錯可以進行處理;記錄出錯時的一些信息

③處理所有的錯誤:

===例子1:

DELIMITER $$

CREATE PROCEDURE small_mistake5(

OUT error VARCHAR(5))

BEGIN

DECLARE CONTINUE HANDLER FOR SQLWARNING,NOT FOUND,SQLEXCEPTION

---》錯誤是1開頭的賦給SQLWARNING,2開頭的NOT FOUND,其他給SQLEXCEPTION

SET error = 'xxxxx';

INSERT INTO teams VALUES(2,27,'third');

END$$

DELIMITER ;

mysql> call small_mistake5(@a);

Query OK, 0 rows affected (0.00 sec)

mysql> select @a;

+-------+

| @a |

+-------+

| xxxxx |

+-------+

1 row in set (0.00 sec)

===忽略一個錯誤:

忽略一個條件

DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN END;

–》碰到1開頭的就過。

五、異常處理嵌套問題

例子1:增加程序的可讀性。

DELIMITER $$

CREATE PROCEDURE small_mistake6(

OUT error VARCHAR(5))

BEGIN

DECLARE non_unique CONDITION FOR SQLSTATE '23000';

DECLARE CONTINUE HANDLER FOR non_unique

begin

SET error = '23000';

select error;

end;

INSERT INTO TEAMS VALUES(2,27,'third');

END$$

DELIMITER ;

mysql> call small_mistake6(@error);

+-------+

| error |

+-------+

| 23000 |

+-------+

1 row in set (0.01 sec)

例子2:異常處理的嵌套

DELIMITER $$

CREATE PROCEDURE small_mistake7()

BEGIN

DECLARE CONTINUE HANDLER FOR SQLSTATE '23000'

SET @processed = 100;

BEGIN

DECLARE CONTINUE HANDLER FOR SQLSTATE '21000'

SET @processed = 200;

INSERT INTO TEAMS VALUES(2,27,'third');

--》出錯,假設能被內層的捕獲,就執行200;若不能被內層捕獲,內層的begin...end就廢了,就執行外層100

END;

END$$

DELIMITER ;

mysql> call small_mistake7;

Query OK, 0 rows affected (0.00 sec)

mysql> select @processed;

+------------+

| @processed |

+------------+

| 100 |

+------------+

1 row in set (0.00 sec)

====小結

當有多層begin…end的時候,最好每層都有自己完善的異常處理。自己異常,自己這層去處理。

六、游標 CURSOR

游標:處理結果集。多行多列

====例子1:

DELIMITER $$

CREATE PROCEDURE number_of_players(

OUT pnumber INTEGER

)

BEGIN

DECLARE a_playerno INTEGER; --》變量1

DECLARE FOUND BOOLEAN DEFAULT TRUE; --》變量2

DECLARE c_players CURSOR FOR --》聲明游標(將游標和sql語句關聯起來)

SELECT playerno FROM PLAYERS;

DECLARE CONTINUE HANDLER FOR NOT FOUND --》異常處理,所有的以2開頭的錯誤

SET FOUND = FALSE; --》異常處理后FOUND變為false

SET pnumber = 0;

OPEN c_players; --》打開游標(將游標和結果集聯系起來)

FETCH c_players INTO a_playerno; --》fetch...into相當于select into

WHILE FOUND DO

SET pnumber = pnumber + 1;

FETCH c_players INTO a_playerno; --》循環中的fetch...into,依次指向結果集的一個

END WHILE;

CLOSE c_players;

END$$

DELIMITER ;

mysql> call number_of_players(@pnumber);

Query OK, 0 rows affected (0.00 sec)

mysql> select @pnumber;

+----------+

| @pnumber |

+----------+

| 14 |

+----------+

1 row in set (0.00 sec)

游標處理方式小結:

定義游標:將一個游標和一個select進行關聯;

打開游標:將一個游標和一個結果集關聯,執行了select;

獲取游標(獲取結果集):需要使用循環進行游標的獲取。

{注意:當獲取到最后一個結果集時,再次執行循環的時候,會報錯,這個錯誤以2開頭,

這個時候,需要定義一個對2開頭的錯誤的捕獲:

DECLARE CONTINUE HANDLER FOR NOT FOUND

SET FOUND = FALSE; }

關閉游標:結果集消失

資源釋放。

七、存儲過程權限問題

mysql>select ROUTINE_NAME,ROUTINE_SCHEMA,ROUTINE_TYPE from ROUTINES where ROUTINE_SCHEMA in('test','TENNIS');

GRANT EXECUTE --》授予執行權限

ON PROCEDURE number_penalties

TO 'u1'@'%';

[root@mysqlstudy ~]# mysql -uu1 -p12345678

mysql: [Warning] Using a password on the command line interface can be insecure.

Welcome to the MySQL monitor. Commands end with ; or \g.

Your MySQL connection id is 7

Server version: 5.7.10 MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use TENNIS;

Database changed

mysql> call number_penalties(44,@pnumber);

Query OK, 0 rows affected (0.01 sec)

mysql> select @pnumber;

+----------+

| @pnumber |

+----------+

| 3 |

+----------+

1 row in set (0.00 sec)

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的mysql游标遍历中sql语句出现异常_MySQL中的异常处理,游标的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。