国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數(shù)據(jù)庫 > MySQL > 正文

MySQL 5.0 新特性教程 存儲(chǔ)過程:第二講

2024-07-24 12:55:08
字體:
供稿:網(wǎng)友
why mysql statements are legal in a procedure body
  什么mysql語句在存儲(chǔ)過程體中是合法的?

  什么樣的sql語句在mysql存儲(chǔ)過程中才是合法的呢?你可以創(chuàng)建一個(gè)包含insert, update,delete, select, drop, create, replace等的語句。你唯一需要記住的是如果代碼中包含mysql擴(kuò)充功能,那么代碼將不能移植。在標(biāo)準(zhǔn)sql語句中:任何數(shù)據(jù)庫定義語言都是合法的,如:

create procedure p () delete from t; //

  set、commit以及rollback也是合法的,如:

create procedure p () set @x = 5; //


  mysql的附加功能:任何數(shù)據(jù)操作語言的語句都將合法。

create procedure p () drop table t; //


  mysql擴(kuò)充功能:直接的select也是合法的:

create procedure p () select 'a'; //


  順便提一下,我將存儲(chǔ)過程中包括ddl語句的功能稱為mysql附加功能的原因是在sql標(biāo)準(zhǔn)中把這個(gè)定義為非核心的,即可選組件。


在過程體中有一個(gè)約束,就是不能有對例程或表操作的數(shù)據(jù)庫操作語句。例如下面的例子就是非法的:

create procedure p1 ()
create procedure p2 () delete from t; //


  下面這些對mysql 5.0來說全新的語句,過程體中是非法的:

create procedure, alter procedure, drop procedure, create function,
drop function, create trigger, drop trigger.


  不過你可以使用

create procedure db5.p1 () drop database db5//


  但是類似

"use database"


  語句也是非法的,因?yàn)閙ysql假定默認(rèn)數(shù)據(jù)庫就是過程的工作場所。

  call the procedure 調(diào)用存儲(chǔ)過程
  1.
  現(xiàn)在我們就可以調(diào)用一個(gè)存儲(chǔ)過程了,你所需要輸入的全部就是call和你過程名以及一個(gè)括號(hào)再一次強(qiáng)調(diào),括號(hào)是必須的當(dāng)你調(diào)用例子里面的p1過程時(shí),結(jié)果是屏幕返回了t表的內(nèi)容

mysql> call p1() //
+------+
| s1 |
+------+
| 5 |
+------+
1 row in set (0.03 sec)
query ok, 0 rows affected (0.03 sec)


  因?yàn)檫^程中的語句是

"select * from t;"

2. let me say that again, another way.
  其他實(shí)現(xiàn)方式

mysql> call p1() //


  和下面語句的執(zhí)行效果一樣:

mysql> select * from t; //


  所以,你調(diào)用p1過程就相當(dāng)于你執(zhí)行了下面語句:

"select * from t;"


  好了,主要的知識(shí)點(diǎn)"創(chuàng)建和調(diào)用過程方法"已經(jīng)清楚了。我希望你能對自己說這相當(dāng)簡單。但是很快我們就有一系列的練習(xí),每次都加一條子句,或者改變已經(jīng)存在的子句。那樣在寫復(fù)雜部件前我們將會(huì)有很多可用的子句。

characteristics clauses 特征子句
  1.

create procedure p2 ()
language sql <--
not deterministic <--
sql security definer <--
comment 'a procedure' <--
select current_date, rand() from t //


  這里我給出的是一些能反映存儲(chǔ)過程特性的子句。子句內(nèi)容在括號(hào)之后,主體之前。這些子句都是可選的,他們有什么作用呢?

  2.

create procedure p2 ()
language sql <--
not deterministic
sql security definer
comment 'a procedure'
select current_date, rand() from t //


  很好,這個(gè)language sql子句是沒有作用的。僅是為了說明下面過程的主體使用sql語言編寫。這條是系統(tǒng)默認(rèn)的,但你在這里聲明是有用的,因?yàn)槟承ヾbms(ibm的db2)需要它,如果你關(guān)注db2的兼容問題最好還是用上。此外,今后可能會(huì)出現(xiàn)除sql外的其他語言支持的存儲(chǔ)過程。

 3.

create procedure p2 ()
language sql
not deterministic <--
sql security definer
comment 'a procedure'
select current_date, rand() from t //


  下一個(gè)子句,not deterministic,是傳遞給系統(tǒng)的信息。這里一個(gè)確定過程的定義就是那些每次輸入一樣輸出也一樣的程序。在這個(gè)案例中,既然主體中含有select語句,那返回肯定是未知的因此我們稱其not deterministic。但是mysql內(nèi)置的優(yōu)化程序不會(huì)注意這個(gè),至少在現(xiàn)在不注意。

  4.

create procedure p2 ()
language sql
not deterministic
sql security definer <--
comment 'a procedure'
select current_date, rand() from t //

  下一個(gè)子句是sql security,可以定義為sql security definer或sql security invoker。
  這就進(jìn)入了權(quán)限控制的領(lǐng)域了,當(dāng)然我們在后面將會(huì)有測試權(quán)限的例子。

sql security definer


  意味著在調(diào)用時(shí)檢查創(chuàng)建過程用戶的權(quán)限(另一個(gè)選項(xiàng)是sqlsecurity invoker)。
  現(xiàn)在而言,使用

sql security definer


  指令告訴mysql服務(wù)器檢查創(chuàng)建過程的用戶就可以了,當(dāng)過程已經(jīng)被調(diào)用,就不檢查執(zhí)行調(diào)用過程的用戶了。而另一個(gè)選項(xiàng)(invoker)則是告訴服務(wù)器在這一步仍然要檢查調(diào)用者的權(quán)限。

  5.

create procedure p2 ()
language sql
not deterministic
sql security definer
comment 'a procedure' <--
select current_date, rand() from t //


  comment 'a procedure'
  是一個(gè)可選的注釋說明。

最后,注釋子句會(huì)跟過程定義存儲(chǔ)在一起。這個(gè)沒有固定的標(biāo)準(zhǔn),我在文中會(huì)指出沒有固定標(biāo)準(zhǔn)的語句,不過幸運(yùn)的是這些在我們標(biāo)準(zhǔn)的sql中很少。

  6.

create procedure p2 ()
language sql
not deterministic
sql security definer
comment ''
select current_date, rand() from t //


  上面過程跟下面語句是等效的:

create procedure p2 ()
select current_date, rand() from t //


  特征子句也有默認(rèn)值,如果省略了就相當(dāng)于:

language sql not deterministic sql security definer comment ''


digressions一些題外話

  digression:
  調(diào)用p2()//的結(jié)果

mysql> call p2() //
+--------------+-----------------+
| current_date | rand() |
+--------------+-----------------+
| 2004-11-09 | 0.7822275075896 |
+--------------+-----------------+
1 row in set (0.26 sec)
query ok, 0 rows affected (0.26 sec)

  當(dāng)調(diào)用過程p2時(shí),一個(gè)select語句被執(zhí)行返回我們期望獲得的隨機(jī)數(shù)。
  digression: sql_mode unchanging
  不會(huì)改變的


sql_mode
mysql> set sql_mode='ansi' //
mysql> create procedure p3()select'a'||'b'//
mysql> set sql_mode=''//
mysql> call p3()//
+------------+
| 'a' || 'b' |
+------------+
| ab |
+------------+


  mysql在過程創(chuàng)建時(shí)會(huì)自動(dòng)保持運(yùn)行環(huán)境。例如:我們需要使用兩條豎線來連接字符串但是這只有在sql mode為ansi的時(shí)候才合法。如果我們將sql mode改為non-ansi,不用擔(dān)心,它仍然能工作,只要它第一次使用時(shí)能正常工作。

exercise 練習(xí)

  question
  問題
  如果你不介意練習(xí)一下的話,試能否不看后面的答案就能處理這些請求。
  創(chuàng)建一個(gè)過程,顯示`hello world`。用大約5秒時(shí)間去思考這個(gè)問題,既然你已經(jīng)學(xué)到了這里,這個(gè)應(yīng)該很簡單。當(dāng)你思考問題的時(shí)候,我們再隨機(jī)選擇一些剛才講過的東西復(fù)習(xí):
  deterministic
  (確定性)子句是反映輸出和輸入依賴特性的子句…調(diào)用過程使用call過程名(參數(shù)列表)方式。好了,我猜時(shí)間也到了。

  answer
  答案
  好的,答案就是在過程體中包含

"select 'hello, world'"

  語句
  mysql

mysql> create procedure p4 () select 'hello, world' //
query ok, 0 rows affected (0.00 sec)
mysql> call p4()//
+--------------+
| hello, world |
+--------------+
| hello, world |
+--------------+
1 row in set (0.00 sec)
query ok, 0 rows affected (0.00 sec)


parameters 參數(shù)

  讓我們更進(jìn)一步的研究怎么在存儲(chǔ)過程中定義參數(shù)
  1. create procedure p5
  () ...
  2. create procedure p5
  ([in] name data-type) ...
  3. create procedure p5
  (out name data-type) ...
  4. create procedure p5
  (inout name data-type) ...

  回憶一下前面講過的參數(shù)列表必須在存儲(chǔ)過程名后的括號(hào)中。上面的第一個(gè)例子中的參數(shù)列表是空的,第二個(gè)例子中有一個(gè)輸入?yún)?shù)。這里的詞in可選,因?yàn)槟J(rèn)參數(shù)為in(input)。

  第三個(gè)例子中有一個(gè)輸出參數(shù),第四個(gè)例子中有一個(gè)參數(shù),既能作為輸入也可以作為輸出。
  in example 輸入的例子

mysql> create procedure p5(p int) set @x = p //
query ok, 0 rows affected (0.00 sec)
mysql> call p5(12345)//
query ok, 0 rows affected (0.00 sec)
mysql> select @x//
+-------+
| @x |
+-------+
| 12345 |
+-------+
1 row in set (0.00 sec)


  這個(gè)in的例子演示的是有輸入?yún)?shù)的過程。在過程體中我將會(huì)話變量x設(shè)定為參數(shù)p的值。然后調(diào)用過程,將12345傳入?yún)?shù)p。選擇顯示會(huì)話變量@x,證明我們已經(jīng)將參數(shù)值12345傳入。
  out example 輸出的例子

mysql> create procedure p6 (out p int)
-> set p = -5 //
mysql> call p6(@y)//
mysql> select @y//
+------+
| @y |
+------+
| -5 |
+------+


  這是另一個(gè)例子。這次的p是輸出參數(shù),然后在過程調(diào)用中將p的值傳入會(huì)話變量@y中。

在過程體中,我們給參數(shù)賦值-5,在調(diào)用后我們可以看出,out是告訴dbms值是從過程中傳出的。
  同樣我們可以用語句

"set @y = -5;"


  來達(dá)到同樣的效果

compound statements 復(fù)合語句

  現(xiàn)在我們展開的詳細(xì)分析一下過程體:

create procedure p7 ()
begin
set @a = 5;
set @b = 5;
insert into t values (@a);
select s1 * @a from t where s1 >= @b;
end; // /* i won't call this.
這個(gè)語句將不會(huì)被調(diào)用
*/


  完成過程體的構(gòu)造就是begin/end塊。這個(gè)begin/end語句塊和pascal語言中的begin/end是基本相同的,和c語言的框架是很相似的。我們可以使用塊去封裝多條語句。在這個(gè)例子中,我們使用了多條設(shè)定會(huì)話變量的語句,然后完成了一些insert和select語句。如果你的過程體中有多條語句,那么你就需要begin/end塊了。begin/end塊也被稱為復(fù)合語句,在這里你可以進(jìn)行變量定義和流程控制。

  未完待續(xù)...


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 安乡县| 梅州市| 宁陵县| 察哈| 秀山| 汤阴县| 罗城| 马山县| 昂仁县| 保定市| 泊头市| 旅游| 镇原县| 东阿县| 太谷县| 南江县| 隆化县| 安阳市| 开平市| 友谊县| 旌德县| 义马市| 开鲁县| 湖南省| 西乌珠穆沁旗| 辽宁省| 奉化市| 丽水市| 唐河县| 白山市| 陈巴尔虎旗| 元谋县| 射洪县| 株洲市| 余姚市| 普洱| 额敏县| 白朗县| 教育| 敦化市| 集贤县|