涉及存儲過程的問題

存儲過程(特定功能的SQL語句集)mysql

  一組爲了完成特定功能的SQL語句集,存儲在數據庫中,通過第一次編譯後再次調用不須要編譯,用戶經過指定存儲過程的名字並給出參數(若是該存儲過程帶有參數)來執行它。存儲過程是數據庫中一個重要對象。程序員

1.建立存儲過程:sql

  create procedure 存儲過程名稱 ([存儲過程參數列表]) [存儲過程特性] SQL代碼內容數據庫

1 例:delimiter  //
2         create procedure proc() 3         begin
4         select * from userinfo; 5       end  //
6       delimiter;

2.建立存儲函數:安全

  create function 存儲函數名稱 ([存儲過程參數列表]) returns type [存儲函數特性] SQL代碼內容服務器

1 例:delimiter //
2         create function NameByZip() 3         returns char(50) 4         return (select username from userinfo where userage='23'); 5       //
6       delimiter;

3.變量的使用網絡

  1)定義變量:declare 局部變量名稱,...數據類型 [default value];併發

    例:declare myparam int default 100;模塊化

  2)爲變量賦值:set 局部變量名稱=expr,var_name=expr,...;函數

    例:declare var1,var2 int;

      set var1=10,var2=10;

4.定義條件和處理程序

  1)定義條件:declare 條件名稱 condition for  sqlstate 'xxxx';

          declare 條件名稱 condition for xxxx;

  2)定義處理程序:捕獲 sqlstate_value: delcare continue handler for sqlstate 'xxxx' set @info='no_such_table';

            捕獲 mysql_error_code: declare continue handler for xxxx set @info='no_such_table';

5.光標的使用

  1)聲明光標:declare 光標名稱 cursor for SQL語句;

  2)打開光標:open 光標名稱;

  3)使用光標:fetch 光標名稱 into 字段名,...;

  4)關閉光標:close 光標名稱;

6.流程控制語句

  if語句:if val is null then select 'val is null';  

      else select 'val is not null';  

      end if;

  case語句:case val

        when 1 then select 'val is 1';

        when 2 then select 'val is 2';

        else select 'val is not 1 or 2';

       end case;

  loop語句:declare id int default 0;

       add_loop:loop;

       set id = id + 1;  

        if id>=10 then leave add_loop;

        end if;

       end loop add_loop;

  leave語句:退出循環語句

  iterate語句:從新執行循環

  repeat語句:declare id int default 0;

        repeat

        set id = id + 1;

        until id >= 10;  ##先執行後判斷

        end repeat;

  while語句:declare id int default 0;

       while id >=10 do  ##先判斷後執行

       set id = id+1;

       end while;

7.調用存儲過程和調用存儲函數

  call 存儲過程名稱(存儲過程定義的參數)

  select 存儲函數名稱(存儲過程定義的參數)

8.查看存儲過程和函數

  show {procedure | function} status like 'x%' 語句查看存儲過程和函數的狀態

  show create {procedure | function} 存儲函數名稱 語句查看存儲過程和函數的定義

9.修改存儲過程和函數

  alter {procedure | function}存儲函數名稱 (存儲過程特性)

10.刪除存儲過程和函數

  drop {procedure | function} [if exists] 存儲函數名稱

存儲過程優缺點:

  優勢:

    1)存儲過程由於SQL語句已經預編譯過了,所以運行的速度比較快;

    2)存儲過程在服務器端運行,減小了客戶端的壓力。

    3)容許模塊化程序設計,就是說只須要建立一次過程,之後在程序中就能夠調用該過程任意次,相似方法的複用;

    4)減小網絡流量,客戶端調用存儲過程只須要傳存儲過程名和相關參數便可,與傳輸SQL語句相比天然數據量少了不少;

    5)加強了使用的安全性,充分利用系統管理員能夠對執行的某一個存儲過程進行權限限制,從而可以實現對某些數據訪問的限制,避免非受權用戶對數據的訪問,保證數據的安全。程序員直接調用存儲過程根本不知道表結構是什麼,有什麼字段,沒有直接暴露表名以及字段名給程序員。

  缺點:

    調試麻煩(至少沒有像開發程序那樣容易),可移植性不靈活(由於存儲過程是依賴於具體的數據庫)。

存儲過程優化思路:

  1)儘可能利用一些SQL語句來代替一些小循環,例如聚合函數、求平均函數等。

  2)中間結果存放於臨時表,加索引;

  3)少使用遊標。SQL是一個集合語言,對於集合運算具備較高的性能。而cursors是過程運算,好比對一個100萬行數據進行查詢,遊標須要讀表100萬次,而不是使用遊標則只須要少許幾回讀取。

  4)事務越短越好,SQL server支持併發操做,若是事務過多過長或隔離級別太高,都會形成併發阻塞、死鎖。致使查詢極慢,CPU佔用率極低。

  5)使用try...catch處理異常;

  6)查詢語句儘可能不要放在循環內;

相關文章
相關標籤/搜索