第7章ストアドプロシージャ

1ストアドプロシージャの概要

        ストアドプロシージャは、データベースサーバーに格納されている一連のSQLステートメントであり、一連のコマンドをカプセル化する関数のように、クエリで指定された名前を呼び出すことによって実行されます。これらのコマンドは、関数名が呼び出されたときに実行されます。

 

ストアドプロシージャの2つの利点

(1)SQL言語の機能と柔軟性の強化ストアドプロシージャは、強力な柔軟性を持ち、複雑な判断やより複雑な計算を完了することができる制御ステートメントを使用して記述できます。

(2)標準コンポーネントプログラミング:ストアドプロシージャの作成後、ストアドプロシージャのSQLステートメントを書き直すことなく、プログラム内で複数回呼び出すことができます。また、データベースの専門家は、アプリケーションのソースコードに影響を与えることなく、いつでもストアドプロシージャを変更できます。

(3)実行速度の高速化:操作に大量のTransaction-SQLコードが含まれている場合、または複数回実行される場合、ストアドプロシージャの実行速度はバッチ処理の実行速度よりもはるかに高速です。ストアドプロシージャがプリコンパイルされているためです。ストアドプロシージャを初めてクエリするとき、オプティマイザはそれを分析して最適化し、最終的にシステムテーブルに格納される実行プランを提供します。ただし、バッチTransaction-SQLステートメントは、実行するたびにコンパイルおよび最適化する必要があり、速度は比較的遅くなります。

(4)ネットワークトラフィックの削減:同じデータベースオブジェクトに対する操作(クエリや変更など)の場合、この操作に関連するTransaction-SQLステートメントがストアドプロシージャに編成されていると、クライアントでストアドプロシージャが呼び出されます。コンピュータ、callステートメントのみがネットワーク上で送信されます。これにより、ネットワークトラフィックが大幅に削減され、ネットワークの負荷が軽減されます。

(5)セキュリティメカニズムとして最大限に活用する:ストアドプロシージャを実行する権限を制限することにより、対応するデータアクセス権限を制限し、不正なユーザーによるデータへのアクセスを回避し、データのセキュリティを確保できます。

 

3ストアドプロシージャの構文を作成します

语法
CREATE PROCEDURE  过程名([[IN|OUT|INOUT] 参数名 数据类型[,[IN|OUT|INOUT] 参数名 数据类型…]]) [特性 ...] 过程体
DELIMITER //
  CREATE PROCEDURE myproc(OUT s int)
    BEGIN
      SELECT COUNT(*) INTO s FROM students;
    END
    //
DELIMITER ;

分隔符
MySQL默认以";"为分隔符,如果没有声明分割符,则编译器会把存储过程当成SQL语句进行处理,因此编译过程会报错,所以要事先用“DELIMITER //”声明当前段分隔符,让编译器把两个"//"之间的内容当做存储过程的代码,不会执行这些代码;“DELIMITER ;”的意为把分隔符还原。

参数
存储过程根据需要可能会有输入、输出、输入输出参数,如果有多个参数用","分割开。MySQL存储过程的参数用在存储过程的定义,共有三种参数类型,IN,OUT,INOUT:
IN参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值
OUT:该值可在存储过程内部被改变,并可返回
INOUT:调用时指定,并且可被改变和返回

过程体
过程体的开始与结束使用BEGIN与END进行标识。 

4基本操作

-- 存储过程 

/**
创建存储过程,并不代表执行存储过程
*/

delimiter //
create
   
    procedure test()
    begin
	insert into a values (null,'11');
	insert into a values (null,'33');
	insert into a values (null,'99');
	insert into a values (null,'11');
    end//
    
delimiter ;

-- 执行调用存储过程
call test();


-- 有输入参数的存储过程
/*
test2(参数。。)   in或者out,inout  参数名字 参数的类型
添加多个参数用,隔开  参数类型可以一样,但是名字要不一样。
*/
delimiter //
create
   
    procedure test2(in number2 varchar(22),number1 varchar(22))
    begin
	insert into a values (null,number1);
    end//
    
delimiter ;

call test2('张三','李四');


-- 有输出参数的存储过程
delimiter //
create
   
    procedure test3(out number int)
    begin
	select count(*)into number from a;
    end//
    
delimiter ;

-- 调用该存储过程    输出参数number的值,保存在aa中
call test3(@aa);

-- 查看aa的值
select @aa;



-- 有输出和输入参数的存储过程
delimiter //
create
   
    procedure test4(message varchar(22),out number int)
    begin
	select count(*)into number from a;
	insert into a values(null,message);
    end//
    
delimiter ;

-- 调用存储过程
call test4('admin',@number);

select @number;



/*****************控制流************/
-- 变量
/*
变量 : 会变的程度
变:变化
量:程度

1 定义
2 赋值

*/

-- if
/**
number 1 在a 表中a_name 就为张三
number 2 在a 表中a_name 就为李四
number 3 在a 表中a_name 就为王武
nubmer为其他数字,就添加aa
*/
delimiter //
create
   
    procedure test5(number int )
    begin
	if number=1   then 
	    insert into a values (null,'张三');
	elseif number=2   then 
	    insert into a values (null,'李四');
	elseif number=3   then 
	    insert into a values (null,'王武');   
	else  
	    insert into a values (null,'aa');	
	end if;	
    end//
delimiter ;

-- 调用存储过程
call test5(44);


--  变量  1 declare  message  varchar(22); 
delimiter //
create
    procedure test6(number int )
    begin
	
	/*声明变量   保存值
	*/
	declare  message  varchar(22); 
	if number=1  then 
		/**赋值*/
	    set message ='张三';
	elseif number=2   then 
	    set message ='李四';
	elseif number=3   then 
	     set message ='王武';
	else  
	   set message ='aa';	
	end if;	
	insert into a values (null,message);	
    end//
delimiter ;


call test6(3);



--  变量  2set @message ='张三';
delimiter //
create
    procedure test7(number int )
    begin

	if number=1  then 
		/**赋值*/
	    set @message ='张三';
	elseif number=2 then 
	    set @message ='李四';
	elseif number=3 then 
	     set @message ='王武';
	else  
	   set @message ='aa';	
	end if;	
	insert into a values (44,@message);	
    end//
delimiter ;

-- 调用
call test7(1);



-- case语句  
delimiter //
create
    procedure test8(number int )
    begin
	case  
	when number =1 then  
	    set @message ='张三';
	    
	when  2 then  
	    set @message ='李四';
	when  3 then  
	    set @message ='王武';
	else  
	    set @message ='aa';
	end case;
	
	insert into a values (44,@message);	
    end//
delimiter ;

call test8(33);


--  循环  LOOP_LABLE
delimiter //
create
    procedure test9( )
    begin
      declare v int default 1;	
     LOOP_LABLE:loop 
      set v=v+1;
      /*打印*/
      select concat('v=',v);
      if v >10 then 
      leave LOOP_LABLE;  
      end if;  
     end loop;		
    end//
delimiter ;

call test9();

おすすめ

転載: blog.csdn.net/yipianfeng_ye/article/details/90636507