mysql 存儲過程

1.存儲過程的建立java

  1. mysql> DELIMITER //  --定義分割符//
  2. mysql> CREATE PROCEDURE proc1(OUT s int)  
  3.     -> BEGIN 
  4.     -> SELECT COUNT(*) INTO s FROM user;  
  5.     -> END 
  6.     -> //  
  7. mysql> DELIMITER ;--恢復mysql默認的分割符;

注:mysql

1)這裏須要注意的是DELIMITER //DELIMITER ;兩句,DELIMITER是分割符的意思,由於MySQL默認以";"爲分隔符,若是咱們沒有聲明分割符,那麼編譯器會把存儲過程當成SQL語句進行處理,則存儲過程的編譯過程會報錯,因此要事先用DELIMITER關鍵字申明當前段分隔符,這樣MySQL纔會將";"當作存儲過程當中的代碼,不會執行這些代碼,用完了以後要把分隔符還原。redis

2)存儲過程根據須要可能會有輸入、輸出、輸入輸出參數,這裏有一個輸出參數s,類型是int型,若是有多個參數用","分割開。sql

3)過程體的開始與結束使用BEGINEND進行標識。數據庫

 

2. 參數express

MySQL存儲過程的參數用在存儲過程的定義,共有三種參數類型,IN,OUT,INOUT,形式如:oop

CREATE PROCEDURE([[IN |OUT |INOUT ] 參數名 數據類形...])spa

IN 輸入參數:表示該參數的值必須在調用存儲過程時指定,在存儲過程當中修改該參數的值不能被返回,爲默認值code

OUT 輸出參數:模式定義的參數只能在過程體內部賦值,表示該參數能夠將某個值傳遞迴調用他的過程(在存儲過程內部,該參數初始值爲 null,不管調用者是否給存儲過程參數設置值)orm

INOUT 輸入輸出參數:調用時指定,而且可被改變和返回

 

 

 

 IN參數實例

##建立存儲過程
DROP
PROCEDURE if exists test1; delimiter// ##定義新的分割符 create procedure test1(in a int) begin select a;##A set a=2; select a;##B select * from worksheet w where w.customer_id=a;##C end// delimiter; ##恢復默認分割符


set @a=1; ##定義變量 call test1(@a); ##調用存儲過程,傳入變量@a
select @a; ##存儲過程當中改變變量@a的值爲2,此時@a的值仍然爲1

 

 

輸出結果:

A.

B.

C.

 

  OUT參數實例:

DROP PROCEDURE if exists test1;
delimiter//
create procedure test1(out a int)
begin
    select a;##A
    set a=2;
    select a;##B
    select * from worksheet w where w.customer_id=a;##C
end//

set @a=1;
call test1(@a);
SELECT @a;##D:變量在存儲過程當中被改變,此時是改變後的值,值爲2.

輸出結果:

A.輸出結果爲null

B.輸出結果爲2.

C.輸出customer_id爲2的數據結果

D.輸出結果爲2

 

DROP PROCEDURE IF EXISTS test1;
DELIMITER //
CREATE PROCEDURE test1(IN input INT,OUT output INT)
BEGIN
    DECLARE var INT DEFAULT 0;
    
    SELECT COUNT(*) INTO output  FROM aaa_test;   ##將數據記錄總數保存到變量output中輸出。     
        
END//


SET @input=0;
CALL test1(@input,@output);
SELECT @output;

 

 

 

INOUT參數實例:

DROP PROCEDURE if exists test1;
delimiter//
create procedure test1(inout a int)
begin
    select a;## A:值爲1
    set a=2;
    select a;## B:值爲2
    select * from worksheet w where w.customer_id=a;## C:值爲customer_id=2的數據列表
end//

set @a=1;
call test1(@a);
SELECT @a;## D :變量@a的值在存儲中改變,此時值爲2.

 

 

 

4.      MySQL存儲過程的調用

 

call和你過程名以及一個括號,括號裏面根據須要,加入參數,參數包括輸入參數、輸出參數、輸入輸出參數。具體的調用方法能夠參看上面的例子。

 

 

5.      MySQL存儲過程的查詢

咱們像知道一個數據庫下面有那些表,咱們通常採用show tables;進行查看。那麼咱們要查看某個數據庫下面的存儲過程,是否也能夠採用呢?答案是,咱們能夠查看某個數據庫下面的存儲過程,可是是令一鍾方式。

咱們能夠用

select name from mysql.proc where db=’數據庫名’;

或者

select routine_name from information_schema.routines where routine_schema='數據庫名';

或者

show procedure status where db='數據庫';

進行查詢。

若是咱們想知道,某個存儲過程的詳細,那咱們又該怎麼作呢?是否是也能夠像操做表同樣用describe 表名進行查看呢?

答案是:咱們能夠查看存儲過程的詳細,可是須要用另外一種方法:

SHOW CREATE PROCEDURE 數據庫.存儲過程名;

就能夠查看當前存儲過程的詳細。

 

6. 變量

變量分爲用戶變量系統變量,系統變量又分爲會話和全局級變量

用戶變量:用戶變量名通常以@開頭,濫用用戶變量會致使程序難以理解及管理

 

DECLARE必須出如今BEGIN  和  EDN之間,且在其它全部語句以前。

  ①申明變量    

DECLARE l_int int unsigned default 4000000;
DECLARE l_numeric number(8,2) DEFAULT 9.95;
DECLARE l_date date DEFAULT '1999-12-31';
DECLARE l_datetime datetime DEFAULT '1999-12-31 23:59:59';
DECLARE l_varchar varchar(255) DEFAULT 'This will not be padded'; 

 

  ②變量賦值

    SET 變量名 = 表達式值 [,variable_name = expression ...]。

    如:set @a='hello world';

   set @b=10;

③使用用戶變量   
      SELECT 10 INTO @b;

或   set @b=10;


  SELECT @b;

DROP PROCEDURE if exists test1;
delimiter //
create procedure test1(inout a int)
begin
    DECLARE vb VARCHAR(30) DEFAULT 'helloworld';
    select vb;##輸出'hello world'
end
//

 

7.條件語句

DROP PROCEDURE if exists test1;
delimiter //
create procedure test1(in input int,out output varchar(30))
begin
    DECLARE var int DEFAULT 0;
    set var=input+1;
    select var;
    if var=1 then
        set output='var =1';
    elseif var =2 then
        set output='var =2';
    elseif var <=10 then
        set output=concat(var ,'<=10');
    else 
        SET output=CONCAT(var ,'>10');
    end if;
end//




SET @input=11;
CALL test1(@input,@output);
SELECT @input;
SELECT @output;

 

8.case…when

DROP PROCEDURE if exists test1;
delimiter //
create procedure test1(in input int,out output varchar(30))
begin
    DECLARE var int DEFAULT 0;
    set var=input+1;
    select var;
    case var
    when 1 then
        set output='var =1';
    when 2 then
        set output='var =2';
    else 
        SET output=concat('var=',var);
    end case;
end//

9.循環語句

建立表:

drop table if exists aaa_test;
create table aaa_test(
    id int primary key auto_increment,
    username varchar(30) not null,
    password varchar(30) not null,
    birthday date not null
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

①while……end while

 

 [ label: ]   WHILE  expression DO

 statements

 END   WHILE   [ label ]  ;

 

DROP PROCEDURE IF EXISTS test1;
DELIMITER //
CREATE PROCEDURE test1(IN input INT,OUT output VARCHAR(30))
BEGIN
    DECLARE var INT DEFAULT 0;
    SET var=input+1;    
    WHILE var<10 DO
        SELECT var;
        INSERT INTO aaa_test(username,PASSWORD,birthday) VALUES(var,CONCAT('pass_',var),'2016-3-24');
        SET var=var+1;
    END WHILE;
END//


SET @input=0;
CALL test1(@input,@output);

查詢表可看到:

 

② repeat ……until ……end repeat

    它在執行操做後檢查結果,而while則是執行前進行檢查。

 [ label: ]  REPEAT

 statements

 UNTIL expression

 END  REPEAT  [ label ]  ;

 

 

DROP PROCEDURE IF EXISTS test1;
DELIMITER //
CREATE PROCEDURE test1(IN input INT,OUT output VARCHAR(30))
BEGIN
    DECLARE var INT DEFAULT 0;
    SET var=input+1;        
    REPEAT
        SELECT var;
        INSERT INTO aaa_test(username,PASSWORD,birthday) VALUES(CONCAT('repeat_name_',var),CONCAT('repeat_pass_',var),CURRENT_TIMESTAMP());
        SET var=var+1;
    UNTIL var >10
    END REPEAT;    
END//


SET @input=0;
CALL test1(@input,@output);

查詢表可看到:

 

③loop……end loop;

[ label: ]  LOOP

  statements

  END  LOOP  [ label ] ;

 

DROP PROCEDURE IF EXISTS test1;
DELIMITER //
CREATE PROCEDURE test1(IN input INT,OUT output VARCHAR(30))
BEGIN
    DECLARE var INT DEFAULT 0;
    SET var=input+1;        
    LOOP_LABEL:LOOP   ##用標籤標記循環 SELECT var;
        INSERT INTO aaa_test(username,PASSWORD,birthday) VALUES(CONCAT('loop_name_',var),CONCAT('loop_pass_',var),CURRENT_TIMESTAMP());
        SET var=var+1;
        IF var >10 THEN
          LEAVE LOOP_LABEL;## leave 跳出標籤標記的循環
      END IF;    
    END LOOP;    
END//


SET @input=0;
CALL test1(@input,@output);

查詢表可看到:

 

④LABLES 標號:

標號能夠用在begin repeat while 或者loop 語句前,語句標號只能在合法的語句前面使用。能夠跳出循環,使運行指令達到複合語句的最後一步。

如上面loop循環中使用的:

  

 ……省略……

LOOP_LABEL:LOOP ##用標籤標記循環
SELECT var; INSERT INTO aaa_test(username,PASSWORD,birthday) VALUES(CONCAT('loop_name_',var),CONCAT('loop_pass_',var),CURRENT_TIMESTAMP()); SET var=var+1; IF var >10 THEN    LEAVE LOOP_LABEL;## leave 跳出標籤標記的循環   END IF; END LOOP;
……省略……

 

⑤ITERATE:

經過引用複合語句的標號,來重新開始複合語句。至關java 中的continue,跳出當前循環後繼續執行。

DROP PROCEDURE if exists test1;
delimiter //
create procedure test1(in input int,out output varchar(30))
begin
    DECLARE var int DEFAULT 0;
    set var=input+1;        
    LOOP_LABEL:loop
        SELECT var;
        
        IF var =3 OR var =4 THEN
            SET var=var+1;
            ITERATE LOOP_LABEL;  ##當var=3或4時,跳出循環。 END IF;    
        
        insert into aaa_test(username,password,birthday) values(concat('iterate_name_',var),concat('iterate_pass_',var),CURRENT_TIMESTAMP());
        set var=var+1;
                    
        if var >10 then
            leave LOOP_LABEL;
        end if;    
    end loop ;    
end//


SET @input=0;
CALL test1(@input,@output);

查詢表可看到:

相關文章
相關標籤/搜索