回答編集履歴

1

調整

2019/09/04 11:44

投稿

yambejp
yambejp

スコア114896

test CHANGED
@@ -9,3 +9,145 @@
9
9
  以前の質問でこういうのがありました
10
10
 
11
11
  - [MYSQLで例外処理について](https://teratail.com/questions/108687)
12
+
13
+
14
+
15
+
16
+
17
+ # sample
18
+
19
+
20
+
21
+ > Bの処理のデータ登録で処理が失敗
22
+
23
+
24
+
25
+ 失敗の種類によりますね
26
+
27
+ - [MySQL :: MySQL 5.6 リファレンスマニュアル :: B.3 サーバーのエラーコードおよびメッセージ](https://dev.mysql.com/doc/refman/5.6/ja/error-messages-server.html)
28
+
29
+
30
+
31
+ で、まず拾いたいエラーを確認します。
32
+
33
+
34
+
35
+ たとえば、tbl_bのプラマリー設定をして重複エラーになる場合
36
+
37
+ ```
38
+
39
+ エラー: 1062 SQLSTATE: 23000 (ER_DUP_ENTRY)
40
+
41
+ メッセージ: '%s' はキー %d で重複しています
42
+
43
+ ```
44
+
45
+ ということで"23000"を拾えば分岐に使えます。
46
+
47
+
48
+
49
+ - tbl_a,tbl_b作成
50
+
51
+ ```SQL
52
+
53
+ create table tbl_a(id int primary key auto_increment,val int);
54
+
55
+ insert into tbl_a values(1,100),(2,110),(3,120);
56
+
57
+ create table tbl_b(id int primary key,val int);
58
+
59
+ insert into tbl_b values(1,200),(2,210),(3,220);
60
+
61
+ ```
62
+
63
+
64
+
65
+ - まずproc_b作成
66
+
67
+ ```SQL
68
+
69
+ drop procedure if exists proc_b;
70
+
71
+ delimiter //
72
+
73
+ create procedure proc_b()
74
+
75
+ begin
76
+
77
+ insert into tbl_b values(4,430);
78
+
79
+ end
80
+
81
+ //
82
+
83
+ delimiter ;
84
+
85
+ ```
86
+
87
+ ※tbl_bに対してprimary keyを指定して投入します。
88
+
89
+ 今回はid=4なので、1回めは成功し、2回目以降は失敗します
90
+
91
+
92
+
93
+ - proc_aを作成
94
+
95
+
96
+
97
+ 上記踏まえproc_aを作成します
98
+
99
+ ```SQL
100
+
101
+ drop procedure if exists proc_a;
102
+
103
+ delimiter //
104
+
105
+ create procedure proc_a()
106
+
107
+ begin
108
+
109
+ declare done int default 0;
110
+
111
+ declare continue handler for sqlstate '23000' set done = 1;
112
+
113
+ call proc_b;
114
+
115
+ if done=0 then
116
+
117
+ insert into tbl_a(val) values(130);
118
+
119
+ end if;
120
+
121
+ end
122
+
123
+ //
124
+
125
+ delimiter ;
126
+
127
+ ```
128
+
129
+ ※命題ではトランザクションをロールバックするような記載でしたが
130
+
131
+ そもそもproc_bがエラーステータス23000を返してこないときだけ投入すればいいでしょう
132
+
133
+
134
+
135
+ # 実行
136
+
137
+ ```SQL
138
+
139
+ call proc_a;
140
+
141
+ ```
142
+
143
+ 1回目は成功するので、tbl_a,tbl_bそれぞれにレコードが1つずつ増えます。
144
+
145
+ 再度proc_aをコールします。
146
+
147
+ ```SQL
148
+
149
+ call proc_a;
150
+
151
+ ```
152
+
153
+ 2回目はproc_bが失敗するのでproc_aもinsert 処理をしません。