測試

原文鏈接:https://blog.csdn.net/weixin_41704733/article/details/79872007
<div id="article_content" class="article_content clearfix">
                                                <div class="article-copyright">
                                                    <svg class="icon" title="CSDN認證原創" aria-hidden="true" style="width:53px; height: 18px; vertical-align: -4px;">
                                <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#CSDN_Cert"></use>
                            </svg>
                        
                        版權聲明:歡迎轉載大宇的博客,轉載請註明出處:                        <a class="copy-right-url" href=" https://blog.csdn.net/yanluandai1985/article/details/83656374" target="_blank"> https://blog.csdn.net/yanluandai1985/article/details/83656374</a>
                    </div>
                                                    <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-3019150162.css">
                                        <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-3019150162.css">
                <div class="htmledit_views" id="content_views">
                                            <h3><a name="t0" target="_blank"></a>&nbsp;10.1.1&nbsp; 創建存儲過程</h3>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 存儲過程就是一條或者多條SQL語句的集合,可以視爲批文件。它可以定義批量插入的語句,也可以定義一個接收不同條件的SQL。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 創建存儲過程的語句爲 CREATE PROCEDURE,創建存儲函數的語句爲CREATE FUNCTION。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 調用存儲過程的語句爲CALL。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 調用存儲函數的形式就像調用MySQL內部函數一樣。&nbsp;</p>

<pre class="has" name="code"><code class="hljs sql"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DROP</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">EXISTS</span> t_student;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> t_student</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">(</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">id</span> <span class="hljs-built_in">INT</span>(<span class="hljs-number">11</span>) PRIMARY <span class="hljs-keyword">KEY</span> AUTO_INCREMENT,</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-keyword">name</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">255</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">  age  <span class="hljs-built_in">INT</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">);</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="9"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="10"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> t_student <span class="hljs-keyword">VALUES</span>(<span class="hljs-literal">NULL</span>,<span class="hljs-string">'大宇'</span>,<span class="hljs-number">22</span>),(<span class="hljs-literal">NULL</span>,<span class="hljs-string">'小宇'</span>,<span class="hljs-number">20</span>);</div></div></li></ol></code><div class="hljs-button {2}" data-title="複製" onclick="hljs.copyCode(event)"></div></pre>

<p>&nbsp;&nbsp;<img alt="" class="has" height="64" src="https://img-blog.csdnimg.cn/20181103135041603.png" width="198"></p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 如上述,t_student表中的數據有兩條。如果我們要分別查詢出來這兩條數據,顯然就是根據ID來查詢。查詢出來了第一條數據以後,我們可能會去做其它的操作。等過兩天,我們要查詢另外一條記錄的時候,可能又要再寫一次這樣的查詢語句。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 如果能像Java那樣,提供一個ID,就能查詢到指定ID的記錄,這樣就可以複用之前寫的SQL語句。對於查詢SQL語句,我們能不能像Java那樣,封裝這個查詢學生的SQL呢?存儲過程與存儲函數應運而生。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 定義一個根據ID查詢學生記錄的存儲過程。</p>

<pre class="has" name="code"><code class="hljs sql"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DROP</span> <span class="hljs-keyword">PROCEDURE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">EXISTS</span> getStuById;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">DELIMITER //  <span class="hljs-comment">-- 定義存儲過程結束符號爲//</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">PROCEDURE</span> getStuById(<span class="hljs-keyword">IN</span> stuId <span class="hljs-built_in">INT</span>(<span class="hljs-number">11</span>),<span class="hljs-keyword">OUT</span> stuName <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">255</span>),<span class="hljs-keyword">OUT</span> stuAge <span class="hljs-built_in">INT</span>(<span class="hljs-number">11</span>)) <span class="hljs-comment">-- 定義輸入與輸出參數</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">COMMENT</span> <span class="hljs-string">'query students by their id'</span>  <span class="hljs-comment">-- 提示信息</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">SQL</span> <span class="hljs-keyword">SECURITY</span> DEFINER  <span class="hljs-comment">-- DEFINER指明只有定義此SQL的人才能執行,MySQL默認也是這個</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">BEGIN</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">   <span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">name</span> ,age <span class="hljs-keyword">INTO</span> stuName , stuAge <span class="hljs-keyword">FROM</span> t_student <span class="hljs-keyword">WHERE</span> <span class="hljs-keyword">id</span> = stuId; <span class="hljs-comment">-- 分號要加</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="9"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">END</span> // <span class="hljs-comment">-- 結束符要加</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="10"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">DELIMITER ;  <span class="hljs-comment">-- 重新定義存儲過程結束符爲分號</span></div></div></li></ol></code><div class="hljs-button {2}" data-title="複製" onclick="hljs.copyCode(event)"></div></pre>

<blockquote>
<p>語法: CREATE PROCEDURE sp_name(定義輸入輸出參數) [ 存儲特性 ]&nbsp; BEGIN SQL語句;&nbsp;&nbsp;END</p>

<p>IN 表示輸入參數,OUT表示輸出參數,INOUT表示既可以輸入也可以輸出的參數。sp_name爲存儲過程的名字。</p>

<p>如果此存儲過程沒有任何輸入輸出,其實就沒什麼意義了,但是sp_name()的括號不能省略。</p>
</blockquote>

<p>&nbsp; &nbsp; &nbsp; &nbsp;查看剛纔創建的存儲過程。</p>

<pre class="has" name="code"><code class="hljs delphi">SHOW <span class="hljs-function"><span class="hljs-keyword">PROCEDURE</span> <span class="hljs-title">STATUS</span> <span class="hljs-title">LIKE</span> '<span class="hljs-title">g</span>%'</span></code><div class="hljs-button {2}" data-title="複製" onclick="hljs.copyCode(event)"></div></pre>

<p>&nbsp;&nbsp;<img alt="" class="has" height="81" src="https://img-blog.csdnimg.cn/20181103142229130.png" width="891"></p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 下面是調用存儲過程。對於存儲過程提供的臨時變量而言,MySQL規定要加上@開頭。</p>

<pre class="has" name="code"><code class="hljs css"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-selector-id">#study</span> 是當前數據庫名稱</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-selector-tag">CALL</span> <span class="hljs-selector-tag">study</span><span class="hljs-selector-class">.getStuById</span>(1,@<span class="hljs-keyword">name</span>,@<span class="hljs-keyword">age</span>);</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-selector-tag">SELECT</span> @<span class="hljs-keyword">name</span> AS stuName,@age AS stuAge;</div></div></li></ol></code><div class="hljs-button {2}" data-title="複製" onclick="hljs.copyCode(event)"></div></pre>

<p>&nbsp;&nbsp;<img alt="" class="has" height="71" src="https://img-blog.csdnimg.cn/20181103140519116.png" width="220"></p>

<pre class="has" name="code"><code class="hljs sql"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">CALL</span> getStuById(<span class="hljs-number">2</span>,@<span class="hljs-keyword">name</span>,@age);</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">SELECT</span> @<span class="hljs-keyword">name</span> <span class="hljs-keyword">AS</span> stuName,@age <span class="hljs-keyword">AS</span> stuAge;</div></div></li></ol></code><div class="hljs-button {2}" data-title="複製" onclick="hljs.copyCode(event)"></div></pre>

<p>&nbsp;&nbsp;<img alt="" class="has" height="81" src="https://img-blog.csdnimg.cn/20181103140542642.png" width="220"></p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 這樣做的好處是,如果一段較爲複雜的SQL語句,我們可能過了幾天再去寫它,又費事又費力。存儲過程可以封裝我們寫過的SQL,在下次需要調用它的時候,直接提供參數並指明查詢結果輸出到哪些變量中即可。</p>

<blockquote>
<p>提示:如果存儲過程一次查詢出兩個記錄,將會提示出錯。[Err] 1172 - Result consisted of more than one row</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;所以需要在存儲過程的SQL後面加上LIMIT 1。從位偏移量爲0的,即從查詢結果的第一條數據開始,查詢一條記錄。</p>
</blockquote>

<h3><a name="t1" target="_blank"></a>10.1.2&nbsp; 創建存儲函數</h3>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 存儲函數與存儲過程本質上是一樣的,都是封裝一系列SQL語句,簡化調用。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 我們自己編寫的存儲函數可以像MySQL函數那樣自由的被調用。</p>

<pre class="has" name="code"><code class="hljs sql"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DROP</span> <span class="hljs-keyword">FUNCTION</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">EXISTS</span> getStuNameById;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">DELIMITER //</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">FUNCTION</span> getStuNameById(stuId <span class="hljs-built_in">INT</span>)  <span class="hljs-comment">-- 默認是IN,但是不能寫上去。stuId視爲輸入的臨時變量</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">RETURNS</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">255</span>)   <span class="hljs-comment">-- 指明返回值類型</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">RETURN</span>  (<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">name</span> <span class="hljs-keyword">FROM</span> t_student <span class="hljs-keyword">WHERE</span> <span class="hljs-keyword">id</span> = stuId); //  <span class="hljs-comment">-- 指明SQL語句,並使用結束標記。注意分號位置</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">DELIMITER ;</div></div></li></ol></code><div class="hljs-button {2}" data-title="複製" onclick="hljs.copyCode(event)"></div></pre>

<p>&nbsp; &nbsp; &nbsp; &nbsp;使用存儲函數。</p>

<pre class="has" name="code"><code class="hljs sql"><span class="hljs-keyword">SELECT</span> getStuNameById(<span class="hljs-number">1</span>);</code><div class="hljs-button {2}" data-title="複製" onclick="hljs.copyCode(event)"></div></pre>

<p>&nbsp;&nbsp;<img alt="" class="has" height="67" src="https://img-blog.csdnimg.cn/20181103143613991.png" width="196"></p>

<blockquote>
<p>提示:在RETURN 語句後面,有趣的是,分號在SQL語句的外面。如果不加分號,查詢結果居然查詢出兩條記錄,很奇怪。</p>
</blockquote>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 從上述存儲函數的寫法上來看,存儲函數有一定的缺點。首先與存儲過程一樣,只能返回一條結果記錄。另外就是存儲函數只能指明一列數據作爲結果,而存儲過程能夠指明多列數據作爲結果。</p>

<h3><a name="t2" target="_blank"></a>10.1.3&nbsp; 定義變量</h3>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 如果希望MySQL執行批量插入的操作,那麼至少要有一個計數器來計算當前插入的是第幾次。&nbsp;</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 這裏的變量是用在存儲過程中的SQL語句中的,變量的作用範圍在BEGIN .... END 中。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 沒有DEFAULT子句,初始值爲NULL。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 定義變量的操作</p>

<pre class="has" name="code"><code class="hljs sql"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DECLARE</span> <span class="hljs-keyword">name</span>,address <span class="hljs-built_in">VARCHAR</span>;  <span class="hljs-comment">-- 發現了嗎,SQL中一般都喜歡先定義變量再定義類型,與Java是相反的。</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DECLARE</span> age <span class="hljs-built_in">INT</span> <span class="hljs-keyword">DEFAULT</span> <span class="hljs-number">20</span>; <span class="hljs-comment">-- 指定默認值。若沒有DEFAULT子句,初始值爲NULL。</span></div></div></li></ol></code><div class="hljs-button {2}" data-title="複製" onclick="hljs.copyCode(event)"></div></pre>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 爲變量賦值</p>

<pre class="has" name="code"><code class="hljs sql"><span class="hljs-keyword">SET</span> <span class="hljs-keyword">name</span> = <span class="hljs-string">'jay'</span>;  <span class="hljs-comment">-- 爲name變量設置值</span></code><div class="hljs-button {2}" data-title="複製" onclick="hljs.copyCode(event)"></div></pre>

<pre class="has" name="code"><code class="hljs sql"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DECLARE</span> var1,var2,var3 <span class="hljs-built_in">INT</span>;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">SET</span> var1 = <span class="hljs-number">10</span>,var2 = <span class="hljs-number">20</span>;  <span class="hljs-comment">-- 其實爲了簡化記憶其語法,可以分開來寫</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-comment">-- SET var1 = 10;</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-comment">-- SET var2 = 20;</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">SET</span> var3 = var1 + var2;</div></div></li></ol></code><div class="hljs-button {2}" data-title="複製" onclick="hljs.copyCode(event)"></div></pre>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 使用變量實例。如下表,在做了去除主鍵約束後,我又添加了一條id=1的數據。現在希望查詢出id爲1的記錄的數量。</p>

<p>&nbsp;<img alt="" class="has" height="94" src="https://img-blog.csdnimg.cn/20181103151418427.png" width="205"></p>

<pre class="has" name="code"><code class="hljs sql"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DROP</span> <span class="hljs-keyword">PROCEDURE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">EXISTS</span> contStById;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">DELIMITER //  <span class="hljs-comment">-- 定義存儲過程結束符號爲//</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">PROCEDURE</span> contStById(<span class="hljs-keyword">IN</span> <span class="hljs-keyword">sid</span> <span class="hljs-built_in">INT</span>(<span class="hljs-number">11</span>),<span class="hljs-keyword">OUT</span> <span class="hljs-keyword">result</span> <span class="hljs-built_in">INT</span>(<span class="hljs-number">11</span>)) <span class="hljs-comment">-- 定義輸入變量</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">BEGIN</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">DECLARE</span> sCount <span class="hljs-built_in">INT</span>;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">COUNT</span>(*) <span class="hljs-keyword">INTO</span> sCount <span class="hljs-keyword">FROM</span> t_student <span class="hljs-keyword">WHERE</span> <span class="hljs-keyword">id</span> = <span class="hljs-keyword">sid</span>;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">SET</span> <span class="hljs-keyword">result</span> = sCount; <span class="hljs-comment">-- 用變量爲輸出結果設值</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="9"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">END</span> // <span class="hljs-comment">-- 結束符要加</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="10"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">DELIMITER ;  <span class="hljs-comment">-- 重新定義存儲過程結束符爲分號</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="11"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="12"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">CALL</span> contStById(<span class="hljs-number">1</span>,@<span class="hljs-keyword">result</span>);</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="13"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">SELECT</span> @<span class="hljs-keyword">result</span>;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="14"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li></ol></code><div class="hljs-button {2}" data-title="複製" onclick="hljs.copyCode(event)"></div></pre>

<p>&nbsp;&nbsp;<img alt="" class="has" height="75" src="https://img-blog.csdnimg.cn/20181103151548824.png" width="215"></p>

<p>&nbsp; &nbsp;顯然,在存儲過程中的變量,可以直接與輸出變量進行相應的計算。本例直接把sCount這個變量的值賦值到輸出中。</p>

<h3><a name="t3" target="_blank"></a>10.1.4&nbsp;定義條件與定義處理程序</h3>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 定義條件CONDITION定義的是:在執行存儲過程中的SQL語句的時候,可能出現的問題。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 定義處理程序HANDLER:定義遇到了指定問題應該如何處理,避免存儲過程執行異常而停止。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 定義條件與定義處理語句程序的位置應該在BEGIN ... END 之間。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 定義條件的語法:DECLARE&nbsp; condtion_name CONDTION&nbsp; FOR&nbsp; 錯誤碼||錯誤值</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 錯誤碼可以視爲一個錯誤的引用,比如404,它代表的就是找不到頁面的錯誤,它的錯誤值可以視爲NullPointerException。</p>

<pre class="has" name="code"><code class="hljs sql"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DECLARE</span> command_not_allowed CONDITION <span class="hljs-keyword">FOR</span> <span class="hljs-keyword">SQLSTATE</span> <span class="hljs-string">'42000'</span>; <span class="hljs-comment">-- 錯誤值</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DECLARE</span> command_not_allowed CONDITION <span class="hljs-keyword">FOR</span> <span class="hljs-number">1148</span>;  <span class="hljs-comment">-- 錯誤碼</span></div></div></li></ol></code><div class="hljs-button {2}" data-title="複製" onclick="hljs.copyCode(event)"></div></pre>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 定義處理程序語法:DECLARE HANDLER_TYPE&nbsp; HANDLER&nbsp; FOR&nbsp; condtion_name sp_statement;</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; MySQL定義了三種HANDLER_TYPE ,CONTIUE是指遇到錯誤忽略,繼續執行下面的SQL。EXIT表示遇到錯誤退出,默認的策略就是EXIT。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; condtion_name可以是我們自己的定義的條件,也可以是MySQL內置的條件,比如SQLWARNING ,匹配01開頭的錯誤代碼。sp_statement指遇到錯誤的時候,需要執行的存儲過程或存儲函數。</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;<img alt="" class="has" height="143" src="https://img-blog.csdnimg.cn/20181103153425980.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3lhbmx1YW5kYWkxOTg1,size_16,color_FFFFFF,t_70" width="601"></p>

<pre class="has" name="code"><code class="hljs sql"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DECLARE</span> CONTINUE <span class="hljs-keyword">HANDLER</span> <span class="hljs-keyword">FOR</span> SQLSATTE <span class="hljs-string">'42S02'</span> <span class="hljs-keyword">SET</span> @info = <span class="hljs-string">'NO_SUCH_TABLE'</span>; <span class="hljs-comment">-- 忽略錯誤值爲42S02的SQL異常</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DECLARE</span> <span class="hljs-keyword">EXIT</span> <span class="hljs-keyword">HANDLER</span> <span class="hljs-keyword">FOR</span> SQLEXCEPTION <span class="hljs-keyword">SET</span> @info = <span class="hljs-string">'ERROR_OCCUR'</span>; <span class="hljs-comment">-- 捕獲SQL執行異常並輸出信息</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DECLARE</span> no_such_table CONDITION <span class="hljs-keyword">FOR</span> <span class="hljs-number">1146</span>; <span class="hljs-comment">-- 爲錯誤碼爲1146的錯誤定義條件</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DECLARE</span> CONTINUE <span class="hljs-keyword">HANDLER</span> <span class="hljs-keyword">FOR</span> no_such_table <span class="hljs-keyword">SET</span> @info = <span class="hljs-string">'no_such_table'</span>; <span class="hljs-comment">-- 爲指定的條件設置處理程序</span></div></div></li></ol></code><div class="hljs-button {2}" data-title="複製" onclick="hljs.copyCode(event)"></div></pre>

<pre class="has" name="code"><code class="hljs sql"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DROP</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">EXISTS</span> t_student;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> t_student</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">(</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">id</span> <span class="hljs-built_in">INT</span>(<span class="hljs-number">11</span>) PRIMARY <span class="hljs-keyword">KEY</span> AUTO_INCREMENT,</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-keyword">name</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">255</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">  age  <span class="hljs-built_in">INT</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">);</div></div></li></ol></code><div class="hljs-button {2}" data-title="複製" onclick="hljs.copyCode(event)"></div></pre>

<p>&nbsp;<img alt="" class="has" height="63" src="https://img-blog.csdnimg.cn/20181103161859370.png" width="188"></p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 現通過存儲過程,爲這張表插入數據。因爲id屬性有主鍵約束,所以不能插入相同的id。</p>

<pre class="has" name="code"><code class="hljs sql"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DROP</span> <span class="hljs-keyword">PROCEDURE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">EXISTS</span> insertStu;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">DELIMITER //  <span class="hljs-comment">-- 定義存儲過程結束符號爲//</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">PROCEDURE</span> insertStu(<span class="hljs-keyword">OUT</span> <span class="hljs-keyword">result</span> <span class="hljs-built_in">INT</span>) <span class="hljs-comment">-- 指定輸出結果</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">BEGIN</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">DECLARE</span> flag <span class="hljs-built_in">INT</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">DEFAULT</span> <span class="hljs-number">0</span>; <span class="hljs-comment">-- 指定變量爲0</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">DECLARE</span> primary_key_limit CONDITION <span class="hljs-keyword">FOR</span> <span class="hljs-keyword">SQLSTATE</span> <span class="hljs-string">'23000'</span>;  <span class="hljs-comment">-- 主鍵約束的錯誤值</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">DECLARE</span> CONTINUE <span class="hljs-keyword">HANDLER</span> <span class="hljs-keyword">FOR</span> primary_key_limit <span class="hljs-keyword">SET</span> @info = <span class="hljs-number">-1</span>; <span class="hljs-comment">-- 設計如果出現錯誤,@info將會被設置爲 -1 </span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="9"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> t_student(<span class="hljs-keyword">id</span>,<span class="hljs-keyword">name</span>,age) <span class="hljs-keyword">VALUES</span>(<span class="hljs-number">1</span>,<span class="hljs-string">'dayu'</span>,<span class="hljs-number">22</span>); <span class="hljs-comment">-- 插入值,設置主鍵爲1</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="10"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">SET</span> flag = <span class="hljs-number">1</span>; <span class="hljs-comment">-- 普通變量設值爲1</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="11"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">SET</span> <span class="hljs-keyword">result</span> = flag;  <span class="hljs-comment">-- 如果下面的SQL執行出現異常,那麼就退出,只有上面的SQL生效。將普通變量的值給輸出</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="12"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> t_student(<span class="hljs-keyword">id</span>,<span class="hljs-keyword">name</span>,age) <span class="hljs-keyword">VALUES</span>(<span class="hljs-number">1</span>,<span class="hljs-string">'dayu'</span>,<span class="hljs-number">22</span>); <span class="hljs-comment">-- 插入值,設置主鍵爲1</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="13"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">SET</span> flag = <span class="hljs-number">2</span>; <span class="hljs-comment">-- 如果處理程序是EXIT,那麼就不會執行到這一步了</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="14"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">SET</span> <span class="hljs-keyword">result</span> = flag; <span class="hljs-comment">-- 將普通變量的值給輸出</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="15"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">END</span> // <span class="hljs-comment">-- 結束符要加</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="16"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">DELIMITER ;  <span class="hljs-comment">-- 重新定義存儲過程結束符爲分號</span></div></div></li></ol></code><div class="hljs-button {2}" data-title="複製" onclick="hljs.copyCode(event)"></div></pre>

<p>&nbsp; &nbsp; &nbsp; &nbsp; CONTIUE是指遇到錯誤忽略,繼續執行下面的SQL。因爲是CONTINUE來處理程序,所以遇到錯誤將會繼續執行。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 另外,第二次插入記錄,因爲違反了主鍵約束,所以插入失敗,但是存儲過程仍然繼續執行完畢。</p>

<pre class="has" name="code"><code class="hljs sql"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">CALL</span> insertStu(@<span class="hljs-keyword">result</span>);</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">SELECT</span> @<span class="hljs-keyword">result</span>,@info; <span class="hljs-comment">-- @info沒有申明就能調用到,可能是是全局變量吧</span></div></div></li></ol></code><div class="hljs-button {2}" data-title="複製" onclick="hljs.copyCode(event)"></div></pre>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 運行結果:&nbsp;</p>

<p>&nbsp;&nbsp;<img alt="" class="has" height="78" src="https://img-blog.csdnimg.cn/20181103163720857.png" width="239"></p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 再次查看t_student表,只插入了一條記錄,但是所有的存儲過程都執行完畢了。&nbsp;</p>

<p>&nbsp;<img alt="" class="has" height="87" src="https://img-blog.csdnimg.cn/20181103163752572.png" width="233">&nbsp;</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 現在,重新執行下面的SQL。先重新建表,再將處理程序的處理策略換爲EXIT:在執行存儲過程中遇到了錯誤,那麼就立即退出。</p>

<pre class="has" name="code"><code class="hljs sql"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DROP</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">EXISTS</span> t_student;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> t_student</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">(</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">id</span> <span class="hljs-built_in">INT</span>(<span class="hljs-number">11</span>) PRIMARY <span class="hljs-keyword">KEY</span> AUTO_INCREMENT,</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-keyword">name</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">255</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">  age  <span class="hljs-built_in">INT</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">);</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="9"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="10"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DROP</span> <span class="hljs-keyword">PROCEDURE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">EXISTS</span> insertStu;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="11"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="12"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">DELIMITER //  <span class="hljs-comment">-- 定義存儲過程結束符號爲//</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="13"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">PROCEDURE</span> insertStu(<span class="hljs-keyword">OUT</span> <span class="hljs-keyword">result</span> <span class="hljs-built_in">INT</span>) <span class="hljs-comment">-- 指定輸出結果</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="14"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">BEGIN</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="15"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">DECLARE</span> flag <span class="hljs-built_in">INT</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">DEFAULT</span> <span class="hljs-number">0</span>; <span class="hljs-comment">-- 指定變量爲0</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="16"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">DECLARE</span> primary_key_limit CONDITION <span class="hljs-keyword">FOR</span> <span class="hljs-keyword">SQLSTATE</span> <span class="hljs-string">'23000'</span>;  <span class="hljs-comment">-- 主鍵約束的錯誤值</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="17"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">DECLARE</span> <span class="hljs-keyword">EXIT</span> <span class="hljs-keyword">HANDLER</span> <span class="hljs-keyword">FOR</span> primary_key_limit <span class="hljs-keyword">SET</span> @info = <span class="hljs-number">-1</span>; <span class="hljs-comment">-- 使用EXIT策略,遇到SQL錯誤將會結束這次存儲過程</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="18"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">                                                               <span class="hljs-comment">-- 出現SQL錯誤則直接退出存儲過程的執行</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="19"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> t_student(<span class="hljs-keyword">id</span>,<span class="hljs-keyword">name</span>,age) <span class="hljs-keyword">VALUES</span>(<span class="hljs-number">1</span>,<span class="hljs-string">'dayu'</span>,<span class="hljs-number">22</span>); <span class="hljs-comment">-- 插入值,設置主鍵爲1</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="20"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">SET</span> flag = <span class="hljs-number">1</span>; <span class="hljs-comment">-- 普通變量設值爲1</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="21"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">SET</span> <span class="hljs-keyword">result</span> = flag;  <span class="hljs-comment">-- 如果下面的SQL執行出現異常,那麼就退出,只有上面的SQL生效。將普通變量的值給輸出</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="22"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> t_student(<span class="hljs-keyword">id</span>,<span class="hljs-keyword">name</span>,age) <span class="hljs-keyword">VALUES</span>(<span class="hljs-number">1</span>,<span class="hljs-string">'dayu'</span>,<span class="hljs-number">22</span>); <span class="hljs-comment">-- 插入值,設置主鍵爲1</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="23"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">SET</span> flag = <span class="hljs-number">2</span>; <span class="hljs-comment">-- 如果處理程序是EXIT,那麼就不會執行到這一步了</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="24"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">SET</span> <span class="hljs-keyword">result</span> = flag; <span class="hljs-comment">-- 將普通變量的值給輸出</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="25"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">END</span> // <span class="hljs-comment">-- 結束符要加</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="26"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">DELIMITER ;  <span class="hljs-comment">-- 重新定義存儲過程結束符爲分號</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="27"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="28"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">CALL</span> insertStu(@<span class="hljs-keyword">result</span>);</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="29"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">SELECT</span> @<span class="hljs-keyword">result</span>,@info; <span class="hljs-comment">-- @info沒有申明就能調用到,可能是是全局變量吧</span></div></div></li></ol></code><div class="hljs-button {2}" data-title="複製" onclick="hljs.copyCode(event)"></div></pre>

<p>&nbsp;<img alt="" class="has" height="84" src="https://img-blog.csdnimg.cn/20181103164240503.png" width="223">&nbsp;&nbsp;</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; @result的結果爲1,說明執行第二條SQL的時候,出現了異常。同樣,@info的值爲-1,也提示處理條件中定義的存儲過程被觸發。最後,數據庫表中的數據也是</p>

<p><img alt="" class="has" height="57" src="https://img-blog.csdnimg.cn/20181103164919201.png" width="221"></p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 如果都是正確的SQL,會是什麼情況呢?</p>

<pre class="has" name="code"><code class="hljs sql"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DROP</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">EXISTS</span> t_student;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> t_student</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">(</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">id</span> <span class="hljs-built_in">INT</span>(<span class="hljs-number">11</span>) PRIMARY <span class="hljs-keyword">KEY</span> AUTO_INCREMENT,</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-keyword">name</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">255</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">  age  <span class="hljs-built_in">INT</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">);</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="9"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="10"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">DROP</span> <span class="hljs-keyword">PROCEDURE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">EXISTS</span> insertStu;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="11"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="12"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">DELIMITER //  <span class="hljs-comment">-- 定義存儲過程結束符號爲//</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="13"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">PROCEDURE</span> insertStu(<span class="hljs-keyword">OUT</span> <span class="hljs-keyword">result</span> <span class="hljs-built_in">INT</span>) <span class="hljs-comment">-- 指定輸出結果</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="14"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">BEGIN</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="15"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">DECLARE</span> flag <span class="hljs-built_in">INT</span>(<span class="hljs-number">11</span>) <span class="hljs-keyword">DEFAULT</span> <span class="hljs-number">0</span>; <span class="hljs-comment">-- 指定變量爲0</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="16"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">DECLARE</span> primary_key_limit CONDITION <span class="hljs-keyword">FOR</span> <span class="hljs-keyword">SQLSTATE</span> <span class="hljs-string">'23000'</span>;  <span class="hljs-comment">-- 主鍵約束的錯誤值</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="17"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">DECLARE</span> <span class="hljs-keyword">EXIT</span> <span class="hljs-keyword">HANDLER</span> <span class="hljs-keyword">FOR</span> primary_key_limit <span class="hljs-keyword">SET</span> @info = <span class="hljs-number">-1</span>; <span class="hljs-comment">-- 設計如果出現錯誤,@info將會被設置爲 -1 </span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="18"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> t_student(<span class="hljs-keyword">id</span>,<span class="hljs-keyword">name</span>,age) <span class="hljs-keyword">VALUES</span>(<span class="hljs-literal">NULL</span>,<span class="hljs-string">'dayu'</span>,<span class="hljs-number">22</span>); <span class="hljs-comment">-- </span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="19"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">SET</span> flag = <span class="hljs-number">1</span>; <span class="hljs-comment">-- 普通變量設值爲1</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="20"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">SET</span> <span class="hljs-keyword">result</span> = flag;  <span class="hljs-comment">-- 如果下面的SQL執行出現異常,那麼就退出,只有上面的SQL生效。將普通變量的值給輸出</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="21"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> t_student(<span class="hljs-keyword">id</span>,<span class="hljs-keyword">name</span>,age) <span class="hljs-keyword">VALUES</span>(<span class="hljs-literal">NULL</span>,<span class="hljs-string">'dayu'</span>,<span class="hljs-number">22</span>); <span class="hljs-comment">-- </span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="22"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">SET</span> flag = <span class="hljs-number">2</span>; <span class="hljs-comment">-- 如果處理程序是EXIT,那麼就不會執行到這一步了</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="23"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">    <span class="hljs-keyword">SET</span> <span class="hljs-keyword">result</span> = flag; <span class="hljs-comment">-- 將普通變量的值給輸出</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="24"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">END</span> // <span class="hljs-comment">-- 結束符要加</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="25"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">DELIMITER ;  <span class="hljs-comment">-- 重新定義存儲過程結束符爲分號</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="26"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="27"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">CALL</span> insertStu(@<span class="hljs-keyword">result</span>);</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="28"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">SELECT</span> @<span class="hljs-keyword">result</span>,@info; <span class="hljs-comment">-- @info沒有申明就能調用到,可能是是全局變量吧</span></div></div></li></ol></code><div class="hljs-button {2}" data-title="複製" onclick="hljs.copyCode(event)"></div></pre>

<p>&nbsp;&nbsp;<img alt="" class="has" height="72" src="https://img-blog.csdnimg.cn/20181103165434188.png" width="211"></p>

<p>&nbsp; &nbsp;<img alt="" class="has" height="71" src="https://img-blog.csdnimg.cn/2018110316544823.png" width="204"></p>

<p>&nbsp; &nbsp; &nbsp; &nbsp;很奇怪,書上說如果遇到異常,將會執行定義條件後面的存儲過程,但是從實際情況來看,當前的存儲過程都是正確的,@info變量的值卻也是-1,我自己也不是太能理解。@result的值爲2的結果說明了存儲過程執行到結尾。從表中的結果來看,也是正確的插入了兩條數據。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp;在回頭琢磨一下書的話:sp_statement參數爲程序語句段,表示在遇到定義錯誤時,需要執行的存儲過程或者函數。可能這裏欠妥吧。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp;總之,下面的核心知識點沒有疑問:在聲明條件後並遇到相關的錯誤條件後,那就看應該怎麼處理。如果是EXIT,那麼存儲過程只生效到錯誤處的上一條SQL。如果是CONTINUE,那麼將會忽略掉執行錯誤的SQL,繼續執行下面的其它存儲過程。</p>

<h3><a name="t4" target="_blank"></a>閱讀更多</h3>

<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<a href="https://blog.csdn.net/yanluandai1985/article/details/83656374" rel="nofollow" data-token="945ce2514f0b0d9ced635cfac5dab479" target="_blank">從頭開始學MySQL-------存儲過程與存儲函數(1)</a></p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; <a href="https://blog.csdn.net/yanluandai1985/article/details/83689524" rel="nofollow" data-token="3e8d0bd2c27233fe4dc9cf511a932cfd" target="_blank">&nbsp;從頭開始學MySQL-------存儲過程與存儲函數(2)</a></p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<a href="https://blog.csdn.net/yanluandai1985/article/details/83653712" rel="nofollow" data-token="6150df0a2bd71af32ad13914b2c885c4" target="_blank">從頭開始學MySQL-------存儲過程與存儲函數(3)</a></p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<a href="https://blog.csdn.net/yanluandai1985/article/details/83715441" rel="nofollow" data-token="67782129d837d1304fc58c3923f7ea4f" target="_blank">從頭開始學MySQL-------存儲過程與存儲函數(4)</a>​​​​​​​</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;目錄貼:<a href="https://blog.csdn.net/yanluandai1985/article/details/89632265" rel="nofollow" data-token="8c005f49e9d9a452973fa69cb0ad370c" target="_blank">從頭開始學MySQL-------目錄帖</a></p>

<p>&nbsp; &nbsp; &nbsp; &nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp; &nbsp; &nbsp;</p>

<p>&nbsp;</p>
                                    </div>
                    </div>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章