1. 程式人生 > >mysql高階包含索引建立優化_函式_儲存過程_觸發器_及遊標

mysql高階包含索引建立優化_函式_儲存過程_觸發器_及遊標

Mysql 高階部分

 

1)索引(index1

2)檢視(view2

3)觸發器(trigger6

4)遊標(cursor8

5)事務(Transaction)10

6)儲存過程(Stored Procedure12

 

(1) 索引(index)

索引是一個單獨的、物理的資料庫結構,它是某個表中一列或若干列值的集合和相應的指向表中物理標識這些值的資料頁的邏輯指標清單。

優點:
   大大加快資料的檢索速度;
   建立唯一性索引,保證資料庫表中每一行資料的唯一性

;
   加速表和表之間的連線;
   在使用分組和排序子句進行資料檢索時,可以顯著減少查詢中分組和排序的時間。

缺點:
    索引需要佔物理空間
    當對錶中的資料進行增加、刪除和修改的時候,索引也要動態的維護,降低了資料的維護速度。


更好的理解索引的提示:

ü 如果經常使用表中的某一列或某幾列為條件進行查詢,且表中的資料量比較大時,可以建立索引,以提高查詢的速度。

ü 索引是與表關聯的可選結構。

ü 通過有目的的建立索引,可以

加快對錶執行SELECT語句的速度。

ü 不管索引是否存在,都無需修改任何SQL語句的書寫方式。索引只是一種快速訪問資料的途徑,它隻影響查詢執行的效率。

ü 可以使用CREATE INDEX命令在一列或若干列的組合上建立索引。

ü 建立索引時,將獲取要建立索引的列,並對其進行排序。然後,將一個指標連同每一行的索引值儲存起來,組成鍵值對(目錄名和頁碼)。使用索引時,系統首先通過已排序的列值執行快速搜尋,然後使用相關聯的指標值來定位具有所要查詢值的行。

ü 一旦建立了索引,MySQL會自動維護和使用它們。

ü 只要修改了資料,如新增新行、更新現有行或刪除行,

MySQL都會自動更新索引。

ü 但是為表建立過多的索引會降低更新、刪除以及插入的效能,因為MySQL還必須更新與該表關聯的索引。


索引的分類

Ø 普通索引這是最基本的索引,它沒有任何限制

Ø 唯一索引它與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一

Ø 主鍵索引(通過主鍵約束間接建立):它是一種特殊的唯一索引,不允許有空值。一般是在建表的時候同時建立主鍵索引

Ø 組合索引:在表中的多個列上建立的索引。組合索引中列的順序是任意的,可以是相鄰的列,也可以是不相鄰的列。

 

索引的建立:

Ø 普通(唯一)索引的建立:

CREATE [UNIQUE] INDEX index_name ON tbl_name(index_col_name,)
index_col_name: col_name[(length)][ASC|DESC]
對於字元型別的列,可以編制字首索引Length表示按照列的指定長度的字串索引

Ø 建立組合索引:

CREATE INDEX index_name ON tbl_name(index_col_name1,index_col_name2,..)

基於(列A,列B)兩列建立索引:

² 可應用索引的情況:A;AB兩列結合;

² 不可用索引的情況:B

² Create index index_name on table_name(A,列B)

Ø 其他建立索引的方式:

² 建立表時建立索引:

CREATE TABLE tbl_name

(

                  列的定義,……,

                  INDEX|KEY [idx_name](index_col_name)

);

Eg:

CREATE TABLE t1

(tid int primary key, #既建立約束,又建立索引

 tname varchar(20),

 index idx_tname(tname), #建立一個普通索引

 tbirthday date

);

² 修改表時建立索引:

ALTER TABLE tbl_name ADD INDEX|KEY [idx_name](indxe_col_name);

Eg:

ALTER TABLE t1 ADD KEY (tbirthday);

Ø 檢視索引:Show index|keys from表名;(SHOW KEYS FROM t1;

Ø 刪除索引:drop index索引名 on表名。(drop index c on t3;

 

(2) 檢視(view)

使用者角度來看,一個檢視是從一個特定的角度來檢視數據庫中的資料。從資料庫系統內部來看,一個檢視是由SELECT語句組成的查詢定義的虛擬表,檢視是由一張或多張表中的資料組成的,從資料庫系統外部來看,檢視就如同一張表一樣,對錶能夠進行的一般操作都可以應用於檢視,例如查詢,插入,修改,刪除操作等。檢視是一個虛擬表,其內容由查詢定義。

 

 

 

概述:

ü  檢視以經過定製的方式顯示來自一個或多個表的資料

ü 檢視是一種資料庫物件,使用者可以象查詢普通表一樣查詢檢視。

ü 檢視內其實沒有儲存任何資料,它只是對錶的一個查詢。

ü 檢視的定義儲存在資料字典內。建立檢視所基於的表為基表

ü 檢視一經定義以後,就可以像表一樣被查詢、修改、刪除和更新

作用:

ü 簡化資料查詢語句

ü 使使用者能從多角度看到同一資料

ü 提高了資料的安全性

ü 提供了一定程度的邏輯獨立性

ü 減少頻寬流量、優化後還可提高執行效率

優點:

ü 提供了另外一種級別的表安全性

ü 隱藏的資料的複雜性

ü 簡化的使用者的SQL命令

ü 通過重新命名列,從另一個角度提供資料

檢視的建立:

CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]

    VIEWview_name [(column_list)]

    AS select_statement

[WITH [CASCADED | LOCAL] CHECK OPTION]

說明:

OR REPLACE給定了OR REPLACE子句,語句能夠替換已有的同名檢視。

ALGORITHM可選的mysql演算法擴充套件,演算法會影響MySQL處理檢視的方式。有以下三個值:

        UNDEFINED--MySQL將選擇所要使用的演算法。如果可能,它傾向於MERGE而不是TEMPTABLE,這是因為MERGE通常更有效,而且如果使用了臨時表,檢視是不可更新的。

        MERGE--會將引用檢視的語句的文字與檢視定義合併起來,使得檢視定義的某一部分取代語句的對應部分。

         TEMPTABLE--檢視的結果將被置於臨時表中,然後使用它執行語句。

veiw_name:檢視名。

column_list要想為檢視的列定義明確的名稱,列出由逗號隔開的列名。column_list中的名稱數目必須等於SELECT語句檢索的列數。若使用與源表或檢視中相同的列名時可以省略column_list

select_statement: 用來建立檢視的SELECT語句,可在SELECT語句中查詢多個表或檢視。但對SELECT語句有以下的限制:

1. 定義檢視的使用者必須對所參照的表或檢視有查詢(即可執行SELECT語句)許可權;

2. 在定義中引用的表或檢視必須存在;

WITH [cascaded|local] CHECK OPTION: 在關於可更新檢視的WITH CHECK OPTION子句中,當檢視是根據另一個檢視定義的時,LOCALCASCADED關鍵字決定了檢查測試的範圍。LOCAL關鍵字對CHECK OPTION進行了限制,使其僅作用在定義的檢視上,CASCADED會對將進行評估的基表進行檢查。如果未給定任一關鍵字,預設值為CASCADEDWITH CHECK OPTION指出在可更新檢視上所進行的修改都要符合select_statement所指定的限制條件,這樣可以確保資料修改後,仍可通過檢視看到修改的資料。

檢視定義服從下述限制:

ü SELECT語句不能包含FROM子句中的子查詢。

ü SELECT語句不能引用系統或使用者變數。

ü SELECT語句不能引用預處理語句引數。

ü 在儲存子程式內,定義不能引用子程式引數或區域性變數。

ü 在定義中引用的表或檢視必須存在。但是,建立了檢視後,能夠捨棄定義引用的表或檢視。要想檢查檢視定義是否存在這類問題,可使用CHECK TABLE語句。

ü 在定義中不能引用TEMPORARY表,不能建立TEMPORARY檢視。

ü 在檢視定義中命名的表必須已存在。

ü 不能將觸發程式與檢視關聯在一起。

修改檢視:

ALTER [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]

    VIEW view_name [(column_list)]

    AS select_statement

    [WITH [CASCADED | LOCAL] CHECK OPTION]

說明:

該語句用於更改已有檢視的定義。其語法與CREATE VIEW類似。該語句需要具有針對檢視的CREATE VIEWDROP許可權,也需要針對SELECT語句中引用的每一列的某些許可權。

 

檢視檢視:

SHOW CREATE VIEWview_name

說明:

該語句給出了1個建立給定檢視的CREATE VIEW語句。

 

刪除檢視:

DROP VIEW [IF EXISTS]

    view_name [,view_name] ...

[RESTRICT | CASCADE]

說明:

DROP VIEW能夠刪除1個或多個檢視。必須在每個檢視上擁有DROP許可權。

可以使用關鍵字IF EXISTS來防止因不存在的檢視而出錯。

如果給定了RESTRICTCASCADE,將解析並忽略它們。

更新檢視:

概述:

Ø 檢視的使用與表一樣,有增刪改查四種操作,且語法也與表相同。

Ø 在檢視上也可以使用修改資料的DML語句,如INSERTUPDATEDELETE可以統稱為通過檢視更新資料

Ø 通過檢視更新資料有如下限制:

ü 一次只能修改一個底層的基表

ü 如果修改違反了基表的約束條件,則無法更新檢視

ü 如果檢視中的列不是表中的原始列(如建立檢視時使用了連線操作符、聚合函式等),則不能通過檢視更新。

檢視更新操作:

Ø 可更新的檢視:要通過檢視更新基本表資料,必須保證檢視是可更新檢視,即可以在INSETUPDATEDELETE等語句當中使用它們。對於可更新的檢視,在檢視中的行和基表中的行之間必須具有一對一的關係。還有一些特定的其他結構,這類結構會使得檢視不可更新。如果檢視包含下述結構中的任何一種,那麼它就是不可更新的: 

ü 聚合函式;

ü DISTINCT關鍵字;

ü GROUP BY子句;

ü ORDER BY子句;

ü HAVING子句;

ü UNION運算子;

ü 位於選擇列表中的子查詢;

ü FROM子句中包含多個表;

ü SELECT語句中引用了不可更新檢視;

Ø 插入資料:使用INSERT語句通過檢視向基本表插入資料

 

注意:

ü 當檢視所依賴的基本表有多個時,不能向該檢視插入資料,因為這將會影響多個基本表。

ü INSERT語句還有一個限制:SELECT語句中必須包含FROM子句中指定表的所有不能為空的列。

Ø 修改資料:使用UPDATE語句可以通過檢視修改基本表的資料

注意:若一個檢視依賴於多個基本表,則一次修改該檢視只能變動一個基本表的資料。

 

Ø 刪除資料:使用DELETE語句可以通過檢視刪除基本表的資料

注意:對依賴於多個基本表的檢視,不能使用DELETE語句。

(3) 觸發器(trigger)

是個特殊的儲存過程,它的執行不是由程式呼叫,也不是手工啟動,而是由事件來觸發,比如當對一個表進行操作( insert,delete, update)時就會啟用它執行。觸發器經常用於加強資料的完整性約束和業務規則等。 觸發器可以從 DBA_TRIGGERS ,USER_TRIGGERS 資料字典中查到。

為什麼要使用觸發器:

ü 可以使用它來檢查或預防壞的資料進入資料庫。

ü 可以改變或取消INSERT、UPDATE、以及DELETE語句。

ü 可以在一個會話中監視資料改變的動作。

建立觸發器:

CREATE [DEFINER = {user | CURRENT_USER }]

 TRIGGER <觸發器名稱>

{ BEFORE | AFTER }

{ INSERT | UPDATE | DELETE }

ON <表名稱>

FOR EACH ROW

<觸發的SQL語句>

       說明:

DEFINERThe DEFINER clause specifies the MySQL account to be used when checking access privileges at trigger activation time. If a user value is given, it should be a MySQL account specified as 'user_name'@'host_name'

觸發器名稱:觸發器必須有名字,最多64個字元,可能後面會附有分隔符.它和MySQL中其他物件的命名方式基本相象

觸發程式的動作時間:BEFORE  AFTER. 可以設定為事件發生前或後.

事件:指明瞭啟用觸發程式的語句的型別。可以是下述值之一:

ü INSERT:將新行插入表時啟用觸發程式,例如,通過INSERTLOAD DATAREPLACE語句。

ü UPDATE:更改某一行時啟用觸發程式,例如,通過UPDATE語句。

ü DELETE:從表中刪除某一行時啟用觸發程式,例如,通過DELETEREPLACE語句。

觸發器是屬於某一個表的:當在這個表上執行插入、更新或刪除操作的時候就導致觸發器的啟用我們不能給同一張表的同一個事件安排兩個觸發器,而且必須引用永久性表不能將觸發程式與TEMPORARY表或檢視關聯起來

觸發間隔:FOR EACH ROW通知觸發器每隔一行執行一次動作,而不是對整個表執行一次

關於舊的和新建立的列的標識
在觸發器的SQL語句中,你可以關聯表中的任意列。但你不能僅使用列的名稱去標識,那會使系統混淆,因為那裡可能會有列的新名(這可能正是你要修改的,你的動作可能正是要修改列名),還有列的舊名存在。因此你必須用這樣的語法來標識:"NEW . column_name"或者"OLD . column_name".這樣在技術上處理(NEW | OLD . column_name)新和舊的列名屬於建立了過渡變數("transition variables")。
對於INSERT語句,只有NEW是合法的;對於DELETE語句,只有OLD才合法;而UPDATE語句可以在和NEW以及OLD同時使用。下面是一個UPDATE中同時使用NEWOLD的例子。

CREATE TRIGGER t21_au
BEFORE UPDATE ON t22
FOR EACH ROW
BEGIN
SET @old = OLD . s1;
SET @new = NEW.s1;
END;

觸發的SQL語句是當觸發程式啟用時執行的語句。如果你打算執行多個語句,可使用BEGIN ... END複合語句結構。這樣,就能使用儲存子程式中允許的相同語句。

刪除觸發器:

DROP TRIGGER [schema_name.]trigger_name

說明:

方案名稱(schema_name)是可選的。如果省略了schema(方案),將從當前方案中捨棄觸發程式。DROP TRIGGER語句需要SUPER許可權

查詢觸發器:

SHOW TRIGGERS [{FROM | IN} db_name]

    [LIKE 'pattern' | WHERE expr]

mysql> SHOW TRIGGERS LIKE 'acc%'\G

*************************** 1. row ***************************

             Trigger: ins_sum

               Event: INSERT

               Table: account

           Statement: SET @sum = @sum + NEW.amount

              Timing: BEFORE

             Created: NULL

            sql_mode:

             Definer: [email protected]

character_set_client: latin1

collation_connection: latin1_swedish_ci

  Database Collation: latin1_swedish_ci

· Trigger The name of the trigger.

· Event The event that causes trigger activation: one of 'INSERT','UPDATE', or'DELETE'.

· Table The table for which the trigger is defined.

· Statement The statement to be executed when the trigger is activated. This is the same as the text shown in the ACTION_STATEMENT column ofINFORMATION_SCHEMA.TRIGGERS.

· Timing One of the two values'BEFORE' or'AFTER'.

· Created Currently, the value of this column is always NULL.

· sql_mode The SQL mode in effect when the trigger executes.

· Definer The account that created the trigger

 

(4) 遊標(cursor

是系統為使用者開設的一個資料緩衝區,存放SQL語句的執行結果。每個遊標區都有一個名字。使用者可以用SQL語句逐一從遊標中獲取記錄,並賦給主變數,交由主語言進一步處理。
  概述:

       遊標提供了一種對從表中檢索出的資料進行操作的靈活手段,就本質而言,遊標實際上是一種能從包括多條資料記錄的結果集中每次提取一條記錄的機制。遊標總是與一條SQL選擇語句相關聯因為遊標由結果集(可以是零條、一條或由相關的選擇語句檢索出的多條記錄)和結果集中指向特定記錄的遊標位置組成。當決定對結果集進行處理時,必須宣告一個指向該結果集的遊標。如果曾經用C 語言寫過對檔案進行處理的程式,那麼遊標就像您開啟檔案所得到的檔案控制代碼一樣,只要檔案開啟成功,該檔案控制代碼就可代表該檔案。對於遊標而言,其道理是相同的。可見遊標能夠實現按與傳統程式讀取平面檔案類似的方式處理來自基礎表的結果集,從而把表中資料以平面檔案的形式呈現給程式。

       遊標實現了對mysql的儲存過程中迴圈讀取資料表中的物件的過程。

遊標的特性:

Ø READ ONLY 只讀,只能取值而不能賦值;

Ø NOT SCROOLABLE 不可回滾,只能順序讀取;

Ø ASENSITIVE 敏感,不能在已經開啟遊標的表上執行update事務;

遊標操作:

宣告遊標:   DECLAREcursor_name CURSOR FORselect_statement

這個語句宣告一個游標。也可以在子程式中定義多個游標,但是一個塊中的每一個游標必須有唯一的名字。

開啟遊標:    OPENcursor_name

遊標FETCHFETCHcursor_name INTOvar_name [,var_name] ...

這個語句用指定的開啟游標讀取下一行(如果有下一行的話),並且前進游標指標。 

關閉遊標CLOSE  CLOSEcursor_name

這個語句關閉先前開啟的游標。如果未被明確地關閉,游標在它被宣告的複合語句的末尾被關閉。

使用遊標的例項:

CREATE PROCEDURE curdemo(tblName VARCHAR(100))

BEGIN

DECLARE done INT DEFAULT 0;

DECLARE b,c INT;

DECLARE cur1 CURSOR FOR SELECT id FROM v_wondyfox;宣告遊標

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done =1;

drop view if exists v_wondyfox ;

set @sql=concat("create view v_wondyfox as select * from ", tblName);

PREPARE stmt1  FROM @sql;

EXECUTE stmt1 ;

DEALLOCATE PREPARE stmt1;

OPEN cur1; 開啟遊標

REPEAT

FETCH cur1 INTO b; 獲取遊標內容

select b;

UNTIL done END REPEAT;

CLOSE cur1; 關閉遊標

 

END

 

 

CREATE PROCEDURE curdemo()

BEGIN

     DECLARE done INT DEFAULT 0;

     DECLARE a CHAR(16);

     DECLARE b,c INT;

     DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;

     DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;

     DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

     OPEN cur1;

     OPEN cur2;

     REPEAT

          FETCH cur1 INTO a, b;

          FETCH cur2 INTO c;

          IF NOT done THEN

              IF b < c THEN

                  INSERT INTO test.t3 VALUES (a,b);

              ELSE

                  INSERT INTO test.t3 VALUES (a,c);

              END IF;

         END IF;

     UNTIL done END REPEAT;

    CLOSE cur1;

    CLOSE cur2;

END

(5) 事務(Transaction)

是訪問並可能更新資料庫中各種資料項的一個程式執行單元(unit)。事務通常由高階資料庫操縱語言或程式語言(如SQLC++Java)書寫的使用者程式的執行所引起,並用形如begin transactionend transaction語句(或函式呼叫)來界定。事務由事務開始(begin transaction)和事務結束(end transaction)之間執行的全體操作組成。一個事務可以是一條SQL語句,一組SQL語句或整個程式。

          特性:

事務應該具有4個屬性:原子性、一致性、隔離性、持續性。這四個屬性通常稱為ACID特性

ü 原子性(atomicity一個事務是一個不可分割的工作單位,事務中包括的諸操作要麼都做,要麼都不做。就是說不允許事務部分的執行。即使因為故障而使事務不能完成,在rollback時也要消除對資料庫的影響!

ü 一致性(consistency事務必須是使資料庫從一個一致性狀態變到另一個一致性狀態。一致性與原子性是密切相關的。就拿網上購物來說,你只有既讓商品出庫又讓商品進入顧客的購物車才能構成事務。

ü 隔離性isolation一個事務的執行不能被其他事務干擾。即一個事務內部的操作及使用的資料對併發的其他事務是隔離的,併發執行的各個事務之間不能互相干擾。如果多個事務併發執行,應象各個事務獨立執行一樣!

ü 永續性(durability持續性也稱永久性(permanence),指一個事務一旦提交,它對資料庫中資料的改變就應該是永久性的。接下來的其他操作或故障不應該對其有任何影響。

          事務處理的兩種方法:

ü begin,rollback,commit來實現

    begin開始一個事務
rollback 事務回滾
commit 事務確認

ü 直接用set來改變mysql的自動提交模式

   MYSQL預設是自動提交的,也就是你提交一個QUERY,它就直接執行!我們可以通過
set autocommit=0 禁止自動提交
set autocommit=1 開啟自動提交
   來實現事務的處理。

 說明:
     
MYSQL中只有INNODBBDB型別的資料表才能支援事務處理!其他的型別是不支援的!一般MYSQL資料庫預設的引擎是MyISAM,這種引擎不支援事務!如果要讓MYSQL支援事務,可以自己手動修改方法如下:

1. 修改c:\appserv\mysql\my.ini檔案,找到skip-InnoDB,在前面加上#,後儲存檔案。
2. 在執行中輸入:services.msc,重啟mysql服務。
3. phpmyadmin中,mysql->show engines;(或執行mysql->show variables like 'have_%'; ),檢視InnoDBYES,即表示資料庫支援InnoDB了。
也就說明支援事務transaction了。
4. 在建立表時,就可以為Storage Engine選擇InnoDB引擎了。如果是以前建立的表,可以使用mysql->alter table table_name type=InnoDB;
mysql->alter table table_name engine=InnoDB;來改變資料表的引擎以支援事務。

 例項:

/*************** transaction--1 *******************/
$conn = mysql_connect('localhost','root','root') or die ("資料連線錯誤!!!");
mysql_select_db('test',$conn);
mysql_query("set names 'GBK'"); //使用GBK中文編碼;
//開始一個事務
mysql_query("BEGIN"); //或者mysql_query("START TRANSACTION");
$sql = "INSERT INTO `user` (`id`, `username`, `sex`) VALUES (NULL, 'test1', '0')";
$sql2 = "INSERT INTO `user` (`did`, `username`, `sex`) VALUES (NULL, 'test1', '0')";//這條我故意寫錯
$res = mysql_query($sql);
$res1 = mysql_query($sql2);
if($res && $res1){
mysql_query("COMMIT");
echo '提交成功。';
}else{
mysql_query("ROLLBACK");
echo '資料回滾。';
}
mysql_query("END");
/**************** transaction--2 *******************/
/*方法二*/
mysql_query("SET AUTOCOMMIT=0"); //設定mysql不自動提交,需自行用commit語句提交
$sql = "INSERT INTO `user` (`id`, `username`, `sex`) VALUES (NULL, 'test1', '0')";
$sql2 = "INSERT INTO `user` (`did`, `username`, `sex`) VALUES (NULL, 'test1', '0')";//這條我故意寫錯
$res = mysql_query($sql);
$res1 = mysql_query($sql2);
if($res && $res1){
mysql_query("COMMIT");
echo '提交成功。';
}else{
mysql_query("ROLLBACK");
echo '資料回滾。';
}
mysql_query("END"); //事務處理完時別忘記mysql_query("SET AUTOCOMMIT=1");自動提交
/**對於不支援事務的MyISAM引擎資料庫可以使用表鎖定的方法**/

//MyISAM & InnoDB都支援,
/*LOCK TABLES可以鎖定用於當前執行緒的表。如果表被其它執行緒鎖定,則造成堵塞,直到可以獲取所有鎖定為止。
UNLOCK TABLES可以釋放被當前執行緒保持的任何鎖定。當執行緒釋出另一個LOCK TABLES時,或當與伺服器的連線被關閉時,所有由當前執行緒鎖定的表被隱含地解鎖。*/

mysql_query("LOCK TABLES `user` WRITE");//鎖住`user`
$sql = "INSERT INTO `user` (`id`, `username`, `sex`) VALUES (NULL, 'test1', '0')";
$res = mysql_query($sql);
if($res){
echo '提交成功。!';
}else{
echo '失敗!';
}
mysql_query("UNLOCK TABLES");//解除鎖定

(6) 儲存過程(Stored Procedure

是一組為了完成特定功能的SQL語句集,是利用SQL Server所提供的Transact-SQL語言所編寫的程式。經編譯後儲存在資料庫中。儲存過程是資料庫中的一個重要物件,使用者通過指定儲存過程的名字並給出引數(如果該儲存過程帶有引數)來執行它。儲存過程是由流控制和SQL語句書寫的過程,這個過程經編譯和優化後儲存在資料庫伺服器中,儲存過程可由應用程式通過一個呼叫來執行,而且允許使用者宣告變數 。同時,儲存過程可以接收和輸出引數、返回執行儲存過程的狀態值,也可以巢狀呼叫。

為什麼要使用儲存過程:

ü 儲存過程是已經被認證的技術!

ü 儲存過程會使系統執行更快!

ü 儲存過程是可複用的元件!它是資料庫邏輯而不是應用程式。

ü 儲存過程將被儲存!

儲存過程的優點:

Ø 儲存過程只在創造時進行編譯,以後每次執行儲存過程都不需再重新編譯,而一般SQL語句每執行一次就編譯一次,所以使用儲存過程可提高資料庫執行速度。 

Ø 當對資料庫進行復雜操作時(如對多個表進行UpdateInsertQueryDelete時),可將此複雜操作用儲存過程封裝起來與資料庫提供的事務處理結合一起使用。 

Ø 儲存過程可以重複使用,可減少資料庫開發人員的工作量。 

Ø 安全性高,可設定只有某此使用者才具有對指定儲存過程的使用權。

儲存過程與函式的區別:

Ø 自定義函式有且只有一個返回值,就像普通的函式一樣,可以直接在表示式中嵌入呼叫。 儲存過程可以沒有返回值,也可以有任意個輸出引數,必須單獨呼叫。

Ø 執行的本質都一樣。只是函式有如只能返回一個變數的限制。而儲存過程可以返回多個。而函式是可以嵌入在sql中使用的,可以在select中呼叫,而儲存過程不行。

Ø 函式限制比較多,比如不能用臨時表,只能用表變數。還有一些函式都不可用等等。而儲存過程的限制相對就比較少

Ø 函式限制比較多,比如不能用臨時表,只能用表變數。還有一些函式都不可用等等。而儲存過程的限制相對就比較少

Ø 一般來說,儲存過程實現的功能要複雜一點,而函式的實現的功能針對性比較強。對於儲存過程來說可以返回引數,而函式只能返回值或者表物件。

Ø 儲存過程一般是作為一個獨立的部分來執行,而函式可以作為查詢語句的一個部分來呼叫,由於函式可以返回一個表物件,因此它可以在查詢語句中位於FROM關鍵字的後面。

建立儲存過程:

CREATE

    [DEFINER = { user | CURRENT_USER }]

    PROCEDURE sp_name ([proc_parameter[,...]])

    [characteristic ...] routine_body

說明:

ü DEFINER指明使用儲存過程的訪問許可權。

ü sp_name:儲存過程名稱。

ü proc_parameter:[ IN | OUT | INOUT ] param_name type

² in表示向儲存過程中傳入引數;儲存過程預設為傳入引數,所以引數in可以省略

² out表示向外傳出引數; 

² inout表示定義的引數可傳入儲存過程,並可以被儲存過程修改後傳出儲存過程

² param_name:引數名;

² type