Mysqlストアドプロシージャとアプリケーションシナリオ

1つは、ストアドプロシージャとは何ですか

簡単に言えば、これは、アプリケーションの機能関数に少し似ている、より複雑な論理関数を実装できる強力な関数を備えたSQLステートメントのセットです。

ストアドプロシージャは、SQLのセットであるトリガーに少し似ていますが、ストアドプロシージャはアクティブに呼び出され、何かがトリガーされた後に自動的に呼び出されるトリガーよりも強力な機能を備えています。

第二に、ストアドプロシージャの特性

入力パラメータと出力パラメータがあり、変数を宣言でき、if / else、case、whileなどの制御ステートメントがあり、ストアドプロシージャを作成することで複雑な論理関数を実現できます。

関数の一般的な機能:モジュール化、カプセル化、コードの再利用。

高速で、最初の実行のみがコンパイルと最適化のステップを実行する必要があり、後続の呼び出しを直接実行できるため、上記のステップが不要になります。

上記の特性に基づいて、高いパフォーマンス要件と複雑なサービスを備えた一部のモジュールをストアドプロシージャに書き込み、アプリケーション層から直接呼び出すことができます。

3つ目は、簡単なストアドプロシージャを作成することです。

3.1基本的な文法

CREATE PROCEDURE pro_now() -- 存储过程名称,自定义
BEGIN -- 开始存储过程
       # 需要执行操作的sql语句集,可对数据表 进行CRUD 操作
       -- insert some sql here

end; -- 结束存储过程

3.2。現在の時刻を照会するためのストアドプロシージャを作成します。

CREATE  PROCEDURE pro_now() 
BEGIN
    SELECT now();
END;

3.3。ストアドプロシージャを呼び出す:call pro_now(); –キーワード "pro_now()"ストアドプロシージャ名を呼び出す

3.4。作成されたストアドプロシージャを表示します。showPROCEDURESTATUS[where name = 'pro_now'];

3.5、ストアドプロシージャを削除します。DROPPROCEDUREpro_now;-"pro_now"ストアドプロシージャ名

第4に、パラメーターを使用してストアドプロシージャを作成します

4.1。入力パラメータを持つストアドプロシージャの場合は、次のキーワードを使用します。

a。例は次のとおりです。

CREATE PROCEDURE pro_now_in(in time  VARCHAR(20) CHARACTER set "utf8")	
        -- CHARACTER set "utf8",设定字符集,解决中文乱码
BEGIN
	 SELECT now(),time;
end;

b、ストアドプロシージャを呼び出します。

  set @time='当前时间';
  call pro_now_in(@time); --  call pro_now_in('当前时间'); 这样也可以

c。結果は次のとおりです。
ここに画像の説明を挿入

4.2出力パラメータを使用したスト​​アドプロシージャ、キーワードを使用:out

a。例は次のとおりです。

CREATE PROCEDURE pro_now_out(out time  VARCHAR(20),out title VARCHAR(20) CHARACTER set utf8)
BEGIN
	 SELECT now(),'当前时间' into time , title;
end;

b、ストアドプロシージャを呼び出します。

call pro_now_out(@times,@title);
SELECT @title AS "标题",@times AS "时间";

c。結果:
ここに画像の説明を挿入

4.3。入出力パラメーターを持つストアード・プロシージャーの場合、キーワードを使用します:inout

a。例は次のとおりです。

CREATE PROCEDURE pro_now_inout(inout name VARCHAR(20),in title VARCHAR(10), out time VARCHAR(10))
BEGIN
	 SELECT CONCAT(name,'<--->',title) AS name,now() into name,time;
end;

b、ストアドプロシージャを呼び出します。

set @name='jack';
set @title='toady';
call pro_now_inout(@name,@title,@time);
select @name as 'name and title',@time as 'time';

c。結果:
ここに画像の説明を挿入
d。理解:

in(入力):名前、タイトル
out(出力):名前、時間
CONCAT(name、 '<—>'、title)文字列の連結、名前の出力に対応し、now()は時間の出力に対応します。

5、制御フローを使用してストアドプロシージャを作成します

5.1。ステートメント
aの場合、例は次のとおりです。

 CREATE PROCEDURE pro_if(in num INT)
     BEGIN
	    DECLARE result VARCHAR(20) CHARACTER set  utf8 DEFAULT null;
	    IF num = 0 THEN  -- 开始if判断,注意用一个等号"="
	        set result='num 为0啦'; -- 满足条件
	    ELSEIF num > 0 THEN -- 下一个if判断
		set result='num 大于 0';
  	    ELSEIF num < 0 THEN
		set result='num 小于 0';
	    ELSE -- 所有条件不满足的情况下
		set result='num is null or other status';
	    end if; -- 结束if 判断 
	    SELECT result;
 end;

b、ストアドプロシージャを呼び出します。

 call pro_if('33');

c。結果は次のとおりです。
ここに画像の説明を挿入
5.2ケースステートメント

a。例は次のとおりです。

     CREATE PROCEDURE pro_case(in num INT)
BEGIN
	DECLARE result VARCHAR(20) CHARACTER set  utf8 DEFAULT null;
	case num  -- 开始case 判断
	when  2 THEN  -- 满足条件执行
		set result='num 值是2';
 	 when -2 THEN  
		set result='num 值是-2';
	else  -- 所有条件不满足,执行
		set result='num 不等于2和-2';
	end case ; -- 结束case语句
	SELECT result;
end;

b、ストアドプロシージャを呼び出します。

call pro_case(-2);

c。結果は次のとおりです。
ここに画像の説明を挿入

5.3、whileループステートメント

a。例は次のとおりです。

CREATE PROCEDURE pro_while(in num INT)
BEGIN
	DECLARE i int;
	DECLARE result int;
	set i=0;
	set result=0;
	while i < num DO -- 开始while 循环
		set result=result+i;
		set i=i+1;
	end while; -- 结束while 循环 
	SELECT result,i;
end;

b、ストアドプロシージャを呼び出します。

call pro_while(100);

c。結果は次のとおりです。
ここに画像の説明を挿入

6つ目は、カーソルループを使用してストアドプロシージャを作成する

1.例は次のとおりです。

CREATE PROCEDURE pro_cursor(out count int)
BEGIN
	declare  paper_id  VARCHAR(1000) ; -- 论文主键id
	declare doctroName VARCHAR(1000) character set gbk; -- 医生名称
	DECLARE paper_hos VARCHAR(1000); -- 医院id
	DECLARE paper_room      VARCHAR(100); -- 医生专业
	declare done int DEFAULT false ; -- 自定义控制游标循环变量,默认false
	DECLARE  my_cursor CURSOR for (SELECT id,authorName,hospitalId,room
							from yee_article_paper_authorid ); -- 定义游标并输入结果集  
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE; -- 绑定控制变量到游标,游标循环结束自动转true 
	OPEN my_cursor; -- 打开游标
	myLoop:LOOP -- 开始循环体,myLoop为自定义循环名,结束循环时用到  
	FETCH my_cursor into paper_id,doctroName,paper_hos,paper_room ;  -- 将游标当前读取行的数据顺序赋予自定义变量12  
	if done THEN -- 判断是否继续循环  
		LEAVE myLoop;-- 结束循环
	END IF;
	 -- 自己要做的事情,在 sql 中直接使用自定义变量即可  
	insert into temp(str_id,name,hospitalId,room) 	
VALUES(paper_id,doctroName,paper_hos,paper_room);
	COMMIT; -- 提交事务
  END  LOOP myLoop; -- 结束 自定义循环体
	CLOSE my_cursor; -- 关闭游标
	# 循环结束后,统计导入个数
	SELECT count(id)  count from temp into count; -- 计算个数
end

カーソルはデータを処理する方法です。結果セットのデータを表示または処理するために、カーソルは結果セットのデータを一度に1行以上参照する機能を提供します。

7、Springmvcがストアドプロシージャを呼び出す

SimpleJdbcCallクラスを使用して、INおよびOUTパラメータを含むストアドプロシージャを呼び出すことができますこの方法は、Apache Derby、DB2、MySQL、Microsoft SQL Server、Oracle、SybaseなどのRDBMSを処理するときに使用できます。

7.1テーブルを作成します。

CREATE TABLE ssers(
   ID   INT NOT NULL AUTO_INCREMENT,
   NAME VARCHAR(20) NOT NULL,
   AGE  INT NOT NULL,
   PRIMARY KEY (ID)
);

7.2ストアドプロシージャを作成します。

DELIMITER $$
DROP PROCEDURE IF EXISTS `TEST`.`getRecord` $$
CREATE PROCEDURE `TEST`.`getRecord` (
IN in_id     INTEGER,
OUT out_name VARCHAR(20)  CHARACTER set "utf8",
OUT out_age  INTEGER
)
BEGIN
   SELECT name, age
   INTO out_name,out_age
   FROM users where id = in_id;
END $$
DELIMITER ;

 

delimiterはMySQLのコマンドであり、このコマンドはストアドプロシージャとは関係ありません。
実際、コマンドが終了したかどうか、およびmysqlを実行できるかどうかをmysqlインタープリターに通知します。
これは、入力ターミネータを変更することです。
デフォルトでは、区切り文字はセミコロン「;」です。

7.3daoレイヤー呼び出しストアドプロシージャ

Public class UserDaoImpl implements UserDao {

    @Autowired
    private JdbcTemplate myJdbc;

    @Autowired
    private DataSource dataSource;


    private UserModel  userModel;

    @Override
    public UserModel getUser(int id){

        //创建jdbccall对象
        SimpleJdbcCall jdbcCall = new SimpleJdbcCall(dataSource).withProcedureName("getRecord");

        //调用存储过程
        SqlParameterSource in   = new MapSqlParameterSource().addValue("in_id", id);
        Map<String, Object> out = jdbcCall.execute(in);

        UserModel user = new UserModel(0,null,0);

        user.setId(id);
        user.setName((String) out.get("out_name"));
        user.setAge((Integer) out.get("out_age"));
        return user;

        //普通的sql查询
        //String SQL     = "select * from users id = ?";
        //UserModel user = myJdbc.queryForObject(SQL,new Object[]{id}, new UserMapper());
        //return user;

    }

}

8.ストアドプロシージャのデメリット

データベースが異なれば文法も大きく異なり、移植が困難です。データベースを変更した場合は、書き直す必要があります。

管理が容易ではない。ストレージプロセスでビジネスロジックを維持しすぎることは容易ではないため、階層的な管理が容易ではなく、混乱しやすい。一般的なストレージプロセスは、高いパフォーマンス要件を持つ個々のビジネスに適している。 、およびその他の必要性は大きくありません。

参照リンク:

https://blog.csdn.net/HaHa_Sir/article/details/79728854

https://www.cnblogs.com/chenpi/p/5136483.html

https://www.w3cschool.cn/wkspring/3yh61mmc.html

おすすめ

転載: blog.csdn.net/weixin_43452467/article/details/113105809