doc-exports/docs/dws/dev/dws_04_0540.html
Lu, Huayi a24ca60074 DWS DEVELOPER 811 version
Reviewed-by: Hasko, Vladimir <vladimir.hasko@t-systems.com>
Co-authored-by: Lu, Huayi <luhuayi@huawei.com>
Co-committed-by: Lu, Huayi <luhuayi@huawei.com>
2023-01-19 13:37:49 +00:00

184 lines
22 KiB
HTML

<a name="EN-US_TOPIC_0000001098814452"></a><a name="EN-US_TOPIC_0000001098814452"></a>
<h1 class="topictitle1">Error Trapping Statements</h1>
<div id="body8662426"><div class="p" id="EN-US_TOPIC_0000001098814452__a6ebf69af502641968ae876623734d1a4">By default, any error occurring in a PL/SQL function aborts execution of the function, and indeed of the surrounding transaction as well. You can trap errors and restore from them by using a <strong id="EN-US_TOPIC_0000001098814452__b842352706205242">BEGIN</strong> block with an <strong id="EN-US_TOPIC_0000001098814452__b842352706205244">EXCEPTION</strong> clause. The syntax is an extension of the normal syntax for a <strong id="EN-US_TOPIC_0000001098814452__b842352706205251">BEGIN</strong> block:<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001098814452__sc4e948748ce04f6988aa977df1979308"><div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
<span class="normal"> 2</span>
<span class="normal"> 3</span>
<span class="normal"> 4</span>
<span class="normal"> 5</span>
<span class="normal"> 6</span>
<span class="normal"> 7</span>
<span class="normal"> 8</span>
<span class="normal"> 9</span>
<span class="normal">10</span>
<span class="normal">11</span>
<span class="normal">12</span></pre></div></td><td class="code"><div><pre><span></span><span class="p">[</span><span class="o">&lt;&lt;</span><span class="n">label</span><span class="o">&gt;&gt;</span><span class="p">]</span><span class="w"></span>
<span class="p">[</span><span class="k">DECLARE</span><span class="w"></span>
<span class="w"> </span><span class="n">declarations</span><span class="p">]</span><span class="w"></span>
<span class="k">BEGIN</span><span class="w"></span>
<span class="w"> </span><span class="n">statements</span><span class="w"></span>
<span class="k">EXCEPTION</span><span class="w"></span>
<span class="w"> </span><span class="k">WHEN</span><span class="w"> </span><span class="n">condition</span><span class="w"> </span><span class="p">[</span><span class="k">OR</span><span class="w"> </span><span class="n">condition</span><span class="w"> </span><span class="p">...]</span><span class="w"> </span><span class="k">THEN</span><span class="w"></span>
<span class="w"> </span><span class="n">handler_statements</span><span class="w"></span>
<span class="w"> </span><span class="p">[</span><span class="k">WHEN</span><span class="w"> </span><span class="n">condition</span><span class="w"> </span><span class="p">[</span><span class="k">OR</span><span class="w"> </span><span class="n">condition</span><span class="w"> </span><span class="p">...]</span><span class="w"> </span><span class="k">THEN</span><span class="w"></span>
<span class="w"> </span><span class="n">handler_statements</span><span class="w"></span>
<span class="w"> </span><span class="p">...]</span><span class="w"></span>
<span class="k">END</span><span class="p">;</span><span class="w"></span>
</pre></div></td></tr></table></div>
</div>
</div>
<p id="EN-US_TOPIC_0000001098814452__ae857ccc48344429fb3401ba3d7b12666">If no error occurs, this form of block simply executes all the statements, and then control passes to the next statement after <strong id="EN-US_TOPIC_0000001098814452__b84235270620542">END</strong>. But if an error occurs within the statements, further processing of the statements is abandoned, and control passes to the <strong id="EN-US_TOPIC_0000001098814452__b842352706205412">EXCEPTION</strong> list. The list is searched for the first condition matching the error that occurred. If a match is found, the corresponding <strong id="EN-US_TOPIC_0000001098814452__en-us_topic_0058965745_b842352706205438">handler_statements</strong> are executed, and then control passes to the next statement after <strong id="EN-US_TOPIC_0000001098814452__en-us_topic_0058965745_b842352706205435">END</strong>. If no match is found, the error propagates out as though the <strong id="EN-US_TOPIC_0000001098814452__b842352706205450">EXCEPTION</strong> clause were not there at all:</p>
<p id="EN-US_TOPIC_0000001098814452__af8eb23b18eac46f7bbef8010bad5cb72">The error can be caught by an enclosing block with <strong id="EN-US_TOPIC_0000001098814452__b84235270620559">EXCEPTION</strong>, or if there is none it aborts processing of the function.</p>
<p id="EN-US_TOPIC_0000001098814452__a0a95971652914374a4540c31125f0d0b">The condition names can be any of those shown in <em id="EN-US_TOPIC_0000001098814452__i154881059114610">GaussDB(DWS) Error Code Reference</em>. The special condition name <strong id="EN-US_TOPIC_0000001098814452__b842352706205613">OTHERS</strong> matches every error type except <strong id="EN-US_TOPIC_0000001098814452__b842352706205612">QUERY_CANCELED</strong>.</p>
<p id="EN-US_TOPIC_0000001098814452__a443c222e55244f6e9014fc947e0fefd0">If a new error occurs within the selected <strong id="EN-US_TOPIC_0000001098814452__en-us_topic_0058965745_b842352706205631">handler_statements</strong>, it cannot be caught by this <strong id="EN-US_TOPIC_0000001098814452__en-us_topic_0058965745_b842352706205641">EXCEPTION</strong> clause, but is propagated out. A surrounding <strong id="EN-US_TOPIC_0000001098814452__b842352706205811">EXCEPTION</strong> clause could catch it.</p>
<p id="EN-US_TOPIC_0000001098814452__aadbe27f342d74087be4f72db73c65da2">When an error is caught by an <strong id="EN-US_TOPIC_0000001098814452__b842352706205859">EXCEPTION</strong> clause, the local variables of the PL/SQL function remain as they were when the error occurred, but all changes to persistent database state within the block are rolled back.</p>
<p id="EN-US_TOPIC_0000001098814452__aaf0a4f29550147a3bbdf71418f7cdb55">Example:</p>
<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001098814452__s4be2570b429a43f5a47a6a9328d0c236"><div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
<span class="normal"> 2</span>
<span class="normal"> 3</span>
<span class="normal"> 4</span>
<span class="normal"> 5</span>
<span class="normal"> 6</span>
<span class="normal"> 7</span>
<span class="normal"> 8</span>
<span class="normal"> 9</span>
<span class="normal">10</span>
<span class="normal">11</span>
<span class="normal">12</span>
<span class="normal">13</span>
<span class="normal">14</span>
<span class="normal">15</span>
<span class="normal">16</span>
<span class="normal">17</span>
<span class="normal">18</span>
<span class="normal">19</span>
<span class="normal">20</span>
<span class="normal">21</span>
<span class="normal">22</span>
<span class="normal">23</span>
<span class="normal">24</span>
<span class="normal">25</span>
<span class="normal">26</span>
<span class="normal">27</span>
<span class="normal">28</span>
<span class="normal">29</span>
<span class="normal">30</span>
<span class="normal">31</span>
<span class="normal">32</span>
<span class="normal">33</span>
<span class="normal">34</span>
<span class="normal">35</span></pre></div></td><td class="code"><div><pre><span></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">mytab</span><span class="p">(</span><span class="n">id</span><span class="w"> </span><span class="nb">INT</span><span class="p">,</span><span class="n">firstname</span><span class="w"> </span><span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">20</span><span class="p">),</span><span class="n">lastname</span><span class="w"> </span><span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">20</span><span class="p">))</span><span class="w"> </span><span class="n">DISTRIBUTE</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">hash</span><span class="p">(</span><span class="n">id</span><span class="p">);</span><span class="w"></span>
<span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="n">mytab</span><span class="p">(</span><span class="n">firstname</span><span class="p">,</span><span class="w"> </span><span class="n">lastname</span><span class="p">)</span><span class="w"> </span><span class="k">VALUES</span><span class="p">(</span><span class="s1">'Tom'</span><span class="p">,</span><span class="w"> </span><span class="s1">'Jones'</span><span class="p">);</span><span class="w"></span>
<span class="k">CREATE</span><span class="w"> </span><span class="k">FUNCTION</span><span class="w"> </span><span class="n">fun_exp</span><span class="p">()</span><span class="w"> </span><span class="k">RETURNS</span><span class="w"> </span><span class="nb">INT</span><span class="w"></span>
<span class="k">AS</span><span class="w"> </span><span class="err">$$</span><span class="w"></span>
<span class="k">DECLARE</span><span class="w"></span>
<span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="nb">INT</span><span class="w"> </span><span class="p">:</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="nb">INT</span><span class="p">;</span><span class="w"></span>
<span class="k">BEGIN</span><span class="w"></span>
<span class="w"> </span><span class="k">UPDATE</span><span class="w"> </span><span class="n">mytab</span><span class="w"> </span><span class="k">SET</span><span class="w"> </span><span class="n">firstname</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'Joe'</span><span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">lastname</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'Jones'</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">:</span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="p">:</span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"></span>
<span class="k">EXCEPTION</span><span class="w"></span>
<span class="w"> </span><span class="k">WHEN</span><span class="w"> </span><span class="n">division_by_zero</span><span class="w"> </span><span class="k">THEN</span><span class="w"></span>
<span class="w"> </span><span class="n">RAISE</span><span class="w"> </span><span class="n">NOTICE</span><span class="w"> </span><span class="s1">'caught division_by_zero'</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="k">RETURN</span><span class="w"> </span><span class="n">x</span><span class="p">;</span><span class="w"></span>
<span class="k">END</span><span class="p">;</span><span class="err">$$</span><span class="w"></span>
<span class="k">LANGUAGE</span><span class="w"> </span><span class="n">plpgsql</span><span class="p">;</span><span class="w"></span>
<span class="k">call</span><span class="w"> </span><span class="n">fun_exp</span><span class="p">();</span><span class="w"></span>
<span class="n">NOTICE</span><span class="p">:</span><span class="w"> </span><span class="n">caught</span><span class="w"> </span><span class="n">division_by_zero</span><span class="w"></span>
<span class="w"> </span><span class="n">fun_exp</span><span class="w"> </span>
<span class="c1">---------</span>
<span class="w"> </span><span class="mi">1</span><span class="w"></span>
<span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="k">row</span><span class="p">)</span><span class="w"></span>
<span class="k">select</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">from</span><span class="w"> </span><span class="n">mytab</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">firstname</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">lastname</span><span class="w"> </span>
<span class="c1">----+-----------+----------</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Tom</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Jones</span><span class="w"></span>
<span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="k">row</span><span class="p">)</span><span class="w"></span>
<span class="k">DROP</span><span class="w"> </span><span class="k">FUNCTION</span><span class="w"> </span><span class="n">fun_exp</span><span class="p">();</span><span class="w"></span>
<span class="k">DROP</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">mytab</span><span class="p">;</span><span class="w"></span>
</pre></div></td></tr></table></div>
</div>
<p id="EN-US_TOPIC_0000001098814452__a35503ad0057748d2bd29e8defef01a41">When control reaches the assignment to <strong id="EN-US_TOPIC_0000001098814452__b8423527062101">y</strong>, it will fail with a <strong id="EN-US_TOPIC_0000001098814452__b8423527062103">division_by_zero</strong> error. This will be caught by the <strong id="EN-US_TOPIC_0000001098814452__b842352706205957">EXCEPTION</strong> clause. The value returned in the <strong id="EN-US_TOPIC_0000001098814452__b14385113114311">RETURN</strong> statement will be the incremented value of <strong id="EN-US_TOPIC_0000001098814452__b53861131173119">x</strong>.</p>
<div class="note" id="EN-US_TOPIC_0000001098814452__ncb9926bb37a143588779efa07f0014ed"><img src="public_sys-resources/note_3.0-en-us.png"><span class="notetitle"> </span><div class="notebody"><p id="EN-US_TOPIC_0000001098814452__a9b033f3957a84b33a89ea82cc28c95fa">A block containing an <strong id="EN-US_TOPIC_0000001098814452__en-us_topic_0058965745_b84235270621156">EXCEPTION</strong> clause is more expensive to enter and exit than a block without one. Therefore, do not use <strong id="EN-US_TOPIC_0000001098814452__b84235270621159">EXCEPTION</strong> without need.</p>
<p id="EN-US_TOPIC_0000001098814452__ac1d92054dc76412ebd75d08e554a5277">In the following scenario, an exception cannot be caught, and the entire transaction rolls back. The threads of the nodes participating the stored procedure exit abnormally due to node failure and network fault, or the source data is inconsistent with that of the table structure of the target table during the COPY FROM operation.</p>
</div></div>
<p id="EN-US_TOPIC_0000001098814452__a3533539975264a42a0580a8cc6f982d2">Example: Exceptions with <strong id="EN-US_TOPIC_0000001098814452__b84235270621221">UPDATE</strong>/<strong id="EN-US_TOPIC_0000001098814452__b84235270621225">INSERT</strong></p>
<p id="EN-US_TOPIC_0000001098814452__a40d6792d296b44ad8ae624adc85db3db">This example uses exception handling to perform either <strong id="EN-US_TOPIC_0000001098814452__b84235270621236">UPDATE</strong> or <strong id="EN-US_TOPIC_0000001098814452__b84235270621238">INSERT</strong>, as appropriate:</p>
<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001098814452__s674d802f9dc44173baabc9fbbbf74e2c"><div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
<span class="normal"> 2</span>
<span class="normal"> 3</span>
<span class="normal"> 4</span>
<span class="normal"> 5</span>
<span class="normal"> 6</span>
<span class="normal"> 7</span>
<span class="normal"> 8</span>
<span class="normal"> 9</span>
<span class="normal">10</span>
<span class="normal">11</span>
<span class="normal">12</span>
<span class="normal">13</span>
<span class="normal">14</span>
<span class="normal">15</span>
<span class="normal">16</span>
<span class="normal">17</span>
<span class="normal">18</span>
<span class="normal">19</span>
<span class="normal">20</span>
<span class="normal">21</span>
<span class="normal">22</span>
<span class="normal">23</span>
<span class="normal">24</span>
<span class="normal">25</span>
<span class="normal">26</span>
<span class="normal">27</span>
<span class="normal">28</span>
<span class="normal">29</span>
<span class="normal">30</span></pre></div></td><td class="code"><div><pre><span></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">db</span><span class="w"> </span><span class="p">(</span><span class="n">a</span><span class="w"> </span><span class="nb">INT</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">);</span><span class="w"></span>
<span class="k">CREATE</span><span class="w"> </span><span class="k">FUNCTION</span><span class="w"> </span><span class="n">merge_db</span><span class="p">(</span><span class="k">key</span><span class="w"> </span><span class="nb">INT</span><span class="p">,</span><span class="w"> </span><span class="k">data</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">)</span><span class="w"> </span><span class="k">RETURNS</span><span class="w"> </span><span class="n">VOID</span><span class="w"> </span><span class="k">AS</span><span class="w"></span>
<span class="err">$$</span><span class="w"></span>
<span class="k">BEGIN</span><span class="w"></span>
<span class="w"> </span><span class="n">LOOP</span><span class="w"></span>
<span class="c1">-- Try updating the key:</span>
<span class="w"> </span><span class="k">UPDATE</span><span class="w"> </span><span class="n">db</span><span class="w"> </span><span class="k">SET</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">data</span><span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">key</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="k">IF</span><span class="w"> </span><span class="k">found</span><span class="w"> </span><span class="k">THEN</span><span class="w"></span>
<span class="w"> </span><span class="k">RETURN</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="k">END</span><span class="w"> </span><span class="k">IF</span><span class="p">;</span><span class="w"></span>
<span class="c1">-- Not there, so try to insert the key. If someone else inserts the same key concurrently, we could get a unique-key failure.</span>
<span class="w"> </span><span class="k">BEGIN</span><span class="w"></span>
<span class="w"> </span><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="n">db</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="k">VALUES</span><span class="w"> </span><span class="p">(</span><span class="k">key</span><span class="p">,</span><span class="w"> </span><span class="k">data</span><span class="p">);</span><span class="w"></span>
<span class="w"> </span><span class="k">RETURN</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="k">EXCEPTION</span><span class="w"> </span><span class="k">WHEN</span><span class="w"> </span><span class="n">unique_violation</span><span class="w"> </span><span class="k">THEN</span><span class="w"></span>
<span class="w"> </span><span class="c1">-- Loop to try the UPDATE again:</span>
<span class="w"> </span><span class="k">END</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="k">END</span><span class="w"> </span><span class="n">LOOP</span><span class="p">;</span><span class="w"></span>
<span class="k">END</span><span class="p">;</span><span class="w"></span>
<span class="err">$$</span><span class="w"></span>
<span class="k">LANGUAGE</span><span class="w"> </span><span class="n">plpgsql</span><span class="p">;</span><span class="w"></span>
<span class="k">SELECT</span><span class="w"> </span><span class="n">merge_db</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="s1">'david'</span><span class="p">);</span><span class="w"></span>
<span class="k">SELECT</span><span class="w"> </span><span class="n">merge_db</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="s1">'dennis'</span><span class="p">);</span><span class="w"></span>
<span class="c1">-- Delete FUNCTION and TABLE:</span>
<span class="k">DROP</span><span class="w"> </span><span class="k">FUNCTION</span><span class="w"> </span><span class="n">merge_db</span><span class="p">;</span><span class="w"></span>
<span class="k">DROP</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">db</span><span class="w"> </span><span class="p">;</span><span class="w"></span>
</pre></div></td></tr></table></div>
</div>
</div>
<div>
<div class="familylinks">
<div class="parentlink"><strong>Parent topic:</strong> <a href="dws_04_0532.html">Control Statements</a></div>
</div>
</div>