存儲過程

#存儲過程:mysql5.0以上。將sql以函數的形式存儲起來共調用,極大地提升了數據庫的處理速度,同時提升了數據庫編程的靈活性。

#定界符,防止被mysql當成sql語句處理
DELIMITER //
	create procedure demo()#函數名
	begin	#過程體的開始與結束使用begin與end進行標識
		select * from 表名
	end	
// DELIMITER ;

#用戶變量:::凡是帶有@的都屬於用戶變量,使用用戶變量要先set @user = '';,不然null;查詢用戶變量select @user;注意,濫用用戶變量易致使程序難以理解或管理。
#註釋:::--單行;/****/多行註釋;
#過程函數參數:::IN/OUT/INOUT 參數名 類型(爲mysql字段類型)

DELIMITER //
 create procedure demo()
		BEGIN
			select * from sp_user;
		END
		// 
DELIMITER;		

#調用
CALL demo();

#獲取數據的所有存儲過程
select * from information_schema.ROUTINES;
select * from information_schema.ROUTINES where specific_name = 'in_param';

#in
DELIMITER //
  CREATE PROCEDURE in_param(IN p_in int)
    BEGIN
    SELECT p_in;
    SET p_in=2;
    SELECT p_in;
    END;
    //
DELIMITER ;
drop procedure in_param;
#調用
SET @p_in=1;
CALL in_param(@p_in);
SELECT @p_in;

#out
DELIMITER //
	CREATE PROCEDURE out_param(OUT p_out int)
		BEGIN
		SELECT p_out;
		set p_out=2;
		select p_out;
		END
// DELIMITER;		
#調用
SET @p_out=1;
CALL out_param(@p_out);
SELECT @p_out;

#inout
DELIMITER //
	CREATE PROCEDURE inout_param(INOUT p_inout int)
		BEGIN
			SELECT p_inout;
			SET p_inout=2;
			SELECT p_inout;
		END
	// 
DELIMITER;		
drop PROCEDURE inout_param;
#調用
SET @p_inout=1;
CALL inout_param(@p_inout) ;
SELECT @p_inout;

SELECT 'Hello World' into @x;
SELECT @x;
SET @y='Goodbye Cruel World';
SELECT @y;
SET @z=1+2+3;
SELECT @z;



#IN/OUT/INPUT參數
#試例1,簡單調用(OUT)。實現調用存儲過程時,傳入 user_id 返回改用戶的user_name
drop PROCEDURE out_demo;
DELIMITER //
 create procedure out_demo(IN my_user_id varchar(32),OUT user_name varchar(32))
		BEGIN
			select name into user_name from Watcher where id = my_user_id;
			select user_name;
		END
		// 
DELIMITER;	
#試例1調用方法:
CALL shoufuyou_statistics.out_demo('5',@user_name);

#試例2,簡單調用(IN)。實現調用存儲過程時,傳入 user_id 返回改用戶的user_name
drop PROCEDURE in_demo;
DELIMITER //
 create procedure in_demo(IN my_user_id varchar(32))
		BEGIN
			declare user_name varchar(32) default '';#因參數中不含有此變量,故需要聲明declare
			select name into user_name from Watcher where id = my_user_id;
			select user_name;
		END
		// 
DELIMITER;	
#試例2調用方法:
CALL shoufuyou_statistics.in_demo('5');

#試例3,簡單調用(INOUT)。實現調用存儲過程時,傳入 user_id 返回改用戶的user_name
drop PROCEDURE inout_demo;
DELIMITER //
 create procedure inout_demo(INOUT my_user_id varchar(32),INOUT user_name varchar(32))
		BEGIN
			set my_user_id = '5';
			set user_name = '易君強';
			select id,name into my_user_id,user_name from Watcher where id = my_user_id;
			select my_user_id,user_name;
		END
		// 
DELIMITER;	
#試例3調用方法:
call inout_demo(@my_user_id,@user_name);#正確
call inout_demo('6',@user_name);#錯誤



###變量做用域  由上自下
DELIMITER //  
	CREATE PROCEDURE default_demo()  
		begin 
			declare x1 varchar(5) default 'outer';  
		begin 
		declare x1 varchar(5) default 'inner';  
			select x1;  
		end;  
			select x1;  
		end;  
	//  
DELIMITER ;  
call default_demo();

###條件語句  
#1.if-then-else
delimiter $$
	create procedure if_demo(IN parameter int)  
		begin 
			declare var int;
			set var = parameter * 1;
			if var = 2 then 
				insert into demo value(3,17);#向表demo中添加信息,注意表的字段數量
			end if;
			if parameter = 0 then 
				update demo set user_email = user_email + 1;#修改表demo的字段user_email值爲自身+1
			else 
				update demo set user_email = user_email + 2;#修改表demo的字段user_email值爲自身+2
			end if;
		end;
		$$
delimiter;		
call if_demo(2);#調用

#2.case語句
DELIMITER //  
	CREATE PROCEDURE case_demo (in parameter int)  
		begin 
			declare var int;  
			set var = parameter + 1;  
		case var  
		when 0 then   
			insert into demo (user_email)values(17);  
		when 1 then   
			insert into demo (user_email)values(18);  
		else   
			insert into demo (user_email)values(19);  
		end case;  
	end;  
	//  
DELIMITER ; 
call case_demo(-1);

###循環語句
#1.while...end while	特色是執行操做前檢查結果
DELIMITER //  
	CREATE PROCEDURE while_demo()  
		begin 
			declare var int;  
			set var = 0;  
			while var < 6 do  
				insert into demo (user_email)values(var);  
			set var = var + 1;  
		end while;  
	end;  
	//  
DELIMITER ; 
call while_demo();

#2.repeat···· end repeat  特色是執行操做後檢查結果,與do..while相似
DELIMITER //  
	CREATE PROCEDURE repeat_demo()  
		begin   
			declare v int;  
			set v = 0;  
			repeat  
				insert into demo (user_email)values(v);  
				set v = v + 1;  
				until v >= 5  
			end repeat;  
		end;  
	//  
DELIMITER ;  
call repeat_demo();

#3.LOOP...END LOOP
DELIMITER //
drop function if exists loop_demo;
  CREATE PROCEDURE loop_demo()
    begin
      declare v int;
      set v = 0;
      LOOP_LABLE:LOOP
        insert into demo (user_email)VALUES(v);
        set v = v + 1;
        if v >= 5 then
          LEAVE LOOP_LABLE;#相似於break,知足條件就跳出
        end if;
      END LOOP;
    end;
  //
DELIMITER ;
call loop_demo();

#3.LOOP...END LOOP--demo---在MySQL中用函數實如今字符串一後面循環拼接n個字符串二
delimiter $$
drop function if exists fun_addStr;
create function fun_addStr(str1 varchar(100),str2 varchar(10),num int) returns varchar(200)
begin
    declare i int default 1;
    declare result varchar(200) default '';
    set result = str1;
    myloop:loop
        set i = i + 1;
        set result = concat(result,str2);
        if i > num then
					leave myloop;
        end if;
    end loop myloop; 
    return result;
end $$
delimiter;
select fun_addStr('字符串一','字符串二',3);

#迭代
#ITERATE	經過引用複合語句的標號,來重新開始複合語句
DELIMITER //
  CREATE PROCEDURE iterate_demo()
  begin
    declare v int;
    set v = 0;
    LOOP_LABLE:LOOP
      if v = 3 then
        set v = v + 1;
        ITERATE LOOP_LABLE;
      end if;
      insert into demo (user_email)VALUES(v);
      set v = v + 1;
      if v >= 5 then
        LEAVE LOOP_LABLE;
      end if;
    END LOOP;
  end;
  //
DELIMITER ;
call iterate_demo();