1.存儲過程的建立java
注:mysql
(1)這裏須要注意的是DELIMITER //和DELIMITER ;兩句,DELIMITER是分割符的意思,由於MySQL默認以";"爲分隔符,若是咱們沒有聲明分割符,那麼編譯器會把存儲過程當成SQL語句進行處理,則存儲過程的編譯過程會報錯,因此要事先用DELIMITER關鍵字申明當前段分隔符,這樣MySQL纔會將";"當作存儲過程當中的代碼,不會執行這些代碼,用完了以後要把分隔符還原。redis
(2)存儲過程根據須要可能會有輸入、輸出、輸入輸出參數,這裏有一個輸出參數s,類型是int型,若是有多個參數用","分割開。sql
(3)過程體的開始與結束使用BEGIN與END進行標識。數據庫
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 數據庫.存儲過程名;
就能夠查看當前存儲過程的詳細。
變量分爲用戶變量和系統變量,系統變量又分爲會話和全局級變量
用戶變量:用戶變量名通常以@開頭,濫用用戶變量會致使程序難以理解及管理
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);
查詢表可看到: