熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> MySQL >> 正文

MySQL 5.0 新特性教程 存儲過程:第二講

2022-06-13   來源: MySQL 

  Why MySQL Statements are Legal in a Procedure Body
  
  什麼MySQL語句在存儲過程體中是合法的?
  
  什麼樣的SQL語句在Mysql存儲過程中才是合法的呢?你可以創建一個包含INSERT UPDATEDELETE SELECT DROP CREATE REPLACE等的語句你唯一需要記住的是如果代碼中包含MySQL擴充功能那麼代碼將不能移植在標准SQL語句中任何數據庫定義語言都是合法的
  
  CREATE PROCEDURE p () DELETE FROM t; //
  
  SETCOMMIT以及ROLLBACK也是合法的
  
  CREATE PROCEDURE p () SET @x = ; //
  
  MySQL的附加功能任何數據操作語言的語句都將合法
  
  CREATE PROCEDURE p () DROP TABLE t; //
  
  MySQL擴充功能直接的SELECT也是合法的
  
  CREATE PROCEDURE p () SELECT a; //
  
  順便提一下我將存儲過程中包括DDL語句的功能稱為MySQL附加功能的原因是在SQL標准中把這個定義為非核心的即可選組件
  
  在過程體中有一個約束就是不能有對例程或表操作的數據庫操作語句例如下面的例子就是非法的
  
  CREATE PROCEDURE p ()
  CREATE PROCEDURE p () DELETE FROM t; //
  
  下面這些對MySQL 來說全新的語句過程體中是非法的:
  
  CREATE PROCEDURE ALTER PROCEDURE DROP PROCEDURE CREATE FUNCTION
  DROP FUNCTION CREATE TRIGGER DROP TRIGGER
  
  不過你可以使用
  
  CREATE PROCEDURE dbp () DROP DATABASE db//
  
  但是類似
  
  USE database
  
  語句也是非法的因為MySQL假定默認數據庫就是過程的工作場所
  
  Call the Procedure 調用存儲過程
  
  現在我們就可以調用一個存儲過程了你所需要輸入的全部就是CALL和你過程名以及一個括號再一次強調括號是必須的當你調用例子裡面的p過程時結果是屏幕返回了t表的內容
  
  mysql> CALL p() //
  ++
  | s |
  ++
  | |
  ++
   row in set ( sec)
  Query OK rows affected ( sec)
  
  因為過程中的語句是
  
  SELECT * FROM t;
  
   Let me say that again another way
  
  其他實現方式
  
  mysql> CALL p() //
  
  和下面語句的執行效果一樣
  
  mysql> SELECT * FROM t; //
  
  所以你調用p過程就相當於你執行了下面語句
  
  SELECT * FROM t;
  
  好了主要的知識點創建和調用過程方法已經清楚了我希望你能對自己說這相當簡單但是很快我們就有一系列的練習每次都加一條子句或者改變已經存在的子句那樣在寫復雜部件前我們將會有很多可用的子句
  
  Characteristics Clauses 特征子句
  
  CREATE PROCEDURE p ()
  LANGUAGE SQL <
  NOT DETERMINISTIC <
  SQL SECURITY DEFINER <
  COMMENT A Procedure <
  SELECT CURRENT_DATE RAND() FROM t //
  
  這裡我給出的是一些能反映存儲過程特性的子句子句內容在括號之後主體之前這些子句都是可選的他們有什麼作用呢?
  
  CREATE PROCEDURE p ()
  LANGUAGE SQL <
  NOT DETERMINISTIC
  SQL SECURITY DEFINER
  COMMENT A Procedure
  SELECT CURRENT_DATE RAND() FROM t //
  
  很好這個LANGUAGE SQL子句是沒有作用的僅是為了說明下面過程的主體使用SQL語言編寫這條是系統默認的但你在這裡聲明是有用的因為某些DBMS(IBM的DB)需要它如果你關注DB的兼容問題最好還是用上此外今後可能會出現除SQL外的其他語言支持的存儲過程
  
  CREATE PROCEDURE p ()
  LANGUAGE SQL
  NOT DETERMINISTIC <
  SQL SECURITY DEFINER
  COMMENT A Procedure
  SELECT CURRENT_DATE RAND() FROM t //
  
  下一個子句NOT DETERMINISTIC是傳遞給系統的信息這裡一個確定過程的定義就是那些每次輸入一樣輸出也一樣的程序在這個案例中既然主體中含有SELECT語句那返回肯定是未知的因此我們稱其NOT DETERMINISTIC但是MySQL內置的優化程序不會注意這個至少在現在不注意
  
  CREATE PROCEDURE p ()
  LANGUAGE SQL
  NOT DETERMINISTIC
  SQL SECURITY DEFINER <
  COMMENT A Procedure
  SELECT CURRENT_DATE RAND() FROM t //
  
  下一個子句是SQL SECURITY可以定義為SQL SECURITY DEFINER或SQL SECURITY INVOKER
  
  這就進入了權限控制的領域了當然我們在後面將會有測試權限的例子
  
  SQL SECURITY DEFINER
  
  意味著在調用時檢查創建過程用戶的權限(另一個選項是SQLSECURITY INVOKER)
  
  現在而言使用
  
  SQL SECURITY DEFINER
  
  指令告訴MySQL服務器檢查創建過程的用戶就可以了當過程已經被調用就不檢查執行調用過程的用戶了而另一個選項(INVOKER)則是告訴服務器在這一步仍然要檢查調用者的權限
  
  CREATE PROCEDURE p ()
  LANGUAGE SQL
  NOT DETERMINISTIC
  SQL SECURITY DEFINER
  COMMENT A Procedure <
  SELECT CURRENT_DATE RAND() FROM t //
  
  COMMENT A procedure
  是一個可選的注釋說明
  
  最後注釋子句會跟過程定義存儲在一起這個沒有固定的標准我在文中會指出沒有固定標准的語句不過幸運的是這些在我們標准的SQL中很少
  
  CREATE PROCEDURE p ()
  LANGUAGE SQL
  NOT DETERMINISTIC
  SQL SECURITY DEFINER
  COMMENT
  SELECT CURRENT_DATE RAND() FROM t //
  
  上面過程跟下面語句是等效的
  
  CREATE PROCEDURE p ()
  SELECT CURRENT_DATE RAND() FROM t //
  
  特征子句也有默認值如果省略了就相當於
  
  LANGUAGE SQL NOT DETERMINISTIC SQL SECURITY DEFINER COMMENT
  
  Digressions一些題外話
  
  Digression:
  調用p()//的結果
  
  mysql> call p() //
  +++
  | CURRENT_DATE | RAND() |
  +++
  | | |
  +++
   row in set ( sec)
  Query OK rows affected ( sec)
  
  當調用過程p一個SELECT語句被執行返回我們期望獲得的隨機數
  
  Digression: sql_mode unchanging
  
  不會改變的
  
  sql_mode
  mysql> set sql_mode=ansi //
  mysql> create procedure p()selecta||b//
  mysql> set sql_mode=//
  mysql> call p()//
  ++
  | a || b |
  ++
  | ab |
  ++
  
  MySQL在過程創建時會自動保持運行環境例如我們需要使用兩條豎線來連接字符串但是這只有在sql mode為ansi的時候才合法如果我們將sql mode改為nonansi不用擔心它仍然能工作只要它第一次使用時能正常工作
  
  Exercise 練習
  
  Question
  問題
  
  如果你不介意練習一下的話試能否不看後面的答案就能處理這些請求
  
  創建一個過程顯示`Hello world`用大約秒時間去思考這個問題既然你已經學到了這裡這個應該很簡單當你思考問題的時候我們再隨機選擇一些剛才講過的東西復習
  
  DETERMINISTIC
  
  (確定性)子句是反映輸出和輸入依賴特性的子句…調用過程使用CALL過程名(參數列表)方式好了我猜時間也到了
  
  Answer
  答案
  
  好的答案就是在過程體中包含
  
  SELECT Hello world
  
  語句
  MySQL
  
  mysql> CREATE PROCEDURE p () SELECT Hello world //
  Query OK rows affected ( sec)
  mysql> CALL p()//
  ++
  | Hello world |
  ++
  | Hello world |
  ++
   row in set ( sec)
  Query OK rows affected ( sec)
  
  Parameters 參數
  
  讓我們更進一步的研究怎麼在存儲過程中定義參數
  
  CREATE PROCEDURE p
  
  ()
  
  CREATE PROCEDURE p
  ([IN] name datatype)
  
  CREATE PROCEDURE p
  (OUT name datatype)
  
  CREATE PROCEDURE p
  (INOUT name datatype)
  
  回憶一下前面講過的參數列表必須在存儲過程名後的括號中上面的第一個例子中的參數列表是空的第二個例子中有一個輸入參數這裡的詞IN可選因為默認參數為IN(input)
  
  第三個例子中有一個輸出參數
From:http://tw.wingwit.com/Article/program/MySQL/201311/29319.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.