forked from docs/doc-exports
Reviewed-by: Pruthi, Vineet <vineet.pruthi@t-systems.com> Co-authored-by: Lu, Huayi <luhuayi@huawei.com> Co-committed-by: Lu, Huayi <luhuayi@huawei.com>
184 lines
20 KiB
HTML
184 lines
20 KiB
HTML
<a name="EN-US_TOPIC_0000001233883211"></a><a name="EN-US_TOPIC_0000001233883211"></a>
|
|
|
|
<h1 class="topictitle1">Error Trapping Statements</h1>
|
|
<div id="body8662426"><div class="p" id="EN-US_TOPIC_0000001233883211__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_0000001233883211__b842352706205242">BEGIN</strong> block with an <strong id="EN-US_TOPIC_0000001233883211__b842352706205244">EXCEPTION</strong> clause. The syntax is an extension of the normal syntax for a <strong id="EN-US_TOPIC_0000001233883211__b842352706205251">BEGIN</strong> block:<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001233883211__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"><<</span><span class="n">label</span><span class="o">>></span><span class="p">]</span>
|
|
<span class="p">[</span><span class="k">DECLARE</span>
|
|
<span class="w"> </span><span class="n">declarations</span><span class="p">]</span>
|
|
<span class="k">BEGIN</span>
|
|
<span class="w"> </span><span class="n">statements</span>
|
|
<span class="k">EXCEPTION</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="n">handler_statements</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="n">handler_statements</span>
|
|
<span class="w"> </span><span class="p">...]</span>
|
|
<span class="k">END</span><span class="p">;</span>
|
|
</pre></div></td></tr></table></div>
|
|
|
|
</div>
|
|
</div>
|
|
<p id="EN-US_TOPIC_0000001233883211__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_0000001233883211__b84235270620542">END</strong>. But if an error occurs inside the executed statement, the statement rolls back and goes to the EXCEPTION list to find the first condition that matches the error. If a match is found, the corresponding <strong id="EN-US_TOPIC_0000001233883211__en-us_topic_0058965745_b842352706205438">handler_statements</strong> are executed, and then control passes to the next statement after <strong id="EN-US_TOPIC_0000001233883211__en-us_topic_0058965745_b842352706205435">END</strong>. If no match is found, the error propagates out as though the <strong id="EN-US_TOPIC_0000001233883211__b842352706205450">EXCEPTION</strong> clause were not there at all:</p>
|
|
<p id="EN-US_TOPIC_0000001233883211__af8eb23b18eac46f7bbef8010bad5cb72">The error can be caught by an enclosing block with <strong id="EN-US_TOPIC_0000001233883211__b84235270620559">EXCEPTION</strong>, or if there is none it aborts processing of the function.</p>
|
|
<p id="EN-US_TOPIC_0000001233883211__a0a95971652914374a4540c31125f0d0b">The <em id="EN-US_TOPIC_0000001233883211__i6262689435">condition</em> name can be any of those shown in SQL standard error codes. The special condition name <strong id="EN-US_TOPIC_0000001233883211__b842352706205613">OTHERS</strong> matches every error type except <strong id="EN-US_TOPIC_0000001233883211__b842352706205612">QUERY_CANCELED</strong>.</p>
|
|
<p id="EN-US_TOPIC_0000001233883211__a443c222e55244f6e9014fc947e0fefd0">If a new error occurs within the selected <strong id="EN-US_TOPIC_0000001233883211__en-us_topic_0058965745_b842352706205631">handler_statements</strong>, it cannot be caught by this <strong id="EN-US_TOPIC_0000001233883211__en-us_topic_0058965745_b842352706205641">EXCEPTION</strong> clause, but is propagated out. A surrounding <strong id="EN-US_TOPIC_0000001233883211__b842352706205811">EXCEPTION</strong> clause could catch it.</p>
|
|
<p id="EN-US_TOPIC_0000001233883211__aadbe27f342d74087be4f72db73c65da2">When an error is caught by an <strong id="EN-US_TOPIC_0000001233883211__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_0000001233883211__aaf0a4f29550147a3bbdf71418f7cdb55">Example:</p>
|
|
<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001233883211__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="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="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="k">AS</span><span class="w"> </span><span class="err">$$</span>
|
|
<span class="k">DECLARE</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="n">y</span><span class="w"> </span><span class="nb">INT</span><span class="p">;</span>
|
|
<span class="k">BEGIN</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="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="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="k">EXCEPTION</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="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="k">RETURN</span><span class="w"> </span><span class="n">x</span><span class="p">;</span>
|
|
<span class="k">END</span><span class="p">;</span><span class="err">$$</span>
|
|
<span class="k">LANGUAGE</span><span class="w"> </span><span class="n">plpgsql</span><span class="p">;</span>
|
|
|
|
<span class="k">CALL</span><span class="w"> </span><span class="n">fun_exp</span><span class="p">();</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="n">fun_exp</span><span class="w"> </span>
|
|
<span class="c1">---------</span>
|
|
<span class="w"> </span><span class="mi">1</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="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="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="p">(</span><span class="mi">1</span><span class="w"> </span><span class="k">row</span><span class="p">)</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="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>
|
|
</pre></div></td></tr></table></div>
|
|
|
|
</div>
|
|
<p id="EN-US_TOPIC_0000001233883211__a35503ad0057748d2bd29e8defef01a41">When control reaches the assignment to <strong id="EN-US_TOPIC_0000001233883211__b8423527062101">y</strong>, it will fail with a <strong id="EN-US_TOPIC_0000001233883211__b8423527062103">division_by_zero</strong> error. This will be caught by the <strong id="EN-US_TOPIC_0000001233883211__b842352706205957">EXCEPTION</strong> clause. The value returned in the <strong id="EN-US_TOPIC_0000001233883211__b14385113114311">RETURN</strong> statement will be the incremented value of <strong id="EN-US_TOPIC_0000001233883211__b53861131173119">x</strong>.</p>
|
|
<div class="note" id="EN-US_TOPIC_0000001233883211__ncb9926bb37a143588779efa07f0014ed"><img src="public_sys-resources/note_3.0-en-us.png"><span class="notetitle"> </span><div class="notebody"><p id="EN-US_TOPIC_0000001233883211__a9b033f3957a84b33a89ea82cc28c95fa">A block containing an <strong id="EN-US_TOPIC_0000001233883211__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_0000001233883211__b84235270621159">EXCEPTION</strong> without need.</p>
|
|
<p id="EN-US_TOPIC_0000001233883211__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_0000001233883211__a3533539975264a42a0580a8cc6f982d2">Example: Exceptions with <strong id="EN-US_TOPIC_0000001233883211__b84235270621221">UPDATE</strong>/<strong id="EN-US_TOPIC_0000001233883211__b84235270621225">INSERT</strong></p>
|
|
<p id="EN-US_TOPIC_0000001233883211__a40d6792d296b44ad8ae624adc85db3db">This example uses exception handling to perform either <strong id="EN-US_TOPIC_0000001233883211__b84235270621236">UPDATE</strong> or <strong id="EN-US_TOPIC_0000001233883211__b84235270621238">INSERT</strong>, as appropriate:</p>
|
|
<div class="codecoloring" codetype="Sql" id="EN-US_TOPIC_0000001233883211__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="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="err">$$</span>
|
|
<span class="k">BEGIN</span>
|
|
<span class="w"> </span><span class="n">LOOP</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="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="k">RETURN</span><span class="p">;</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="c1">-- Not there, so try to insert the key. If someone else inserts the same key concurrently, there could be a unique-key failure.</span>
|
|
<span class="w"> </span><span class="k">BEGIN</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="k">RETURN</span><span class="p">;</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="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="k">END</span><span class="w"> </span><span class="n">LOOP</span><span class="p">;</span>
|
|
<span class="k">END</span><span class="p">;</span>
|
|
<span class="err">$$</span>
|
|
<span class="k">LANGUAGE</span><span class="w"> </span><span class="n">plpgsql</span><span class="p">;</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="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="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="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>
|
|
</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>
|
|
|