MySQL ---存儲過程和觸發器

MySQL存儲過程和觸發器

存儲過程

1、一個簡單的存儲過程html

1,一個簡單的存儲過程mysql

delimiter $$
	create procedure testa()
	begin
	 Select * from emp;
	 Select * from dept;
	 End;
	$$;
	delimiter ;
	-- 調用存儲過程
	call testa();

存儲過程的結構組成:sql

1,建立格式:create procedure 存儲過程名編程

2,包含一個以上代碼塊,代碼塊使用begin和end之間網絡

3,在命令行中建立須要定義分隔符 delimiter $$函數

2,存儲過程的特色ui

1,能完成複雜的判斷和運算spa

2,可編程性強,靈活命令行

3,SQL編程的代碼可重複使用code

4,執行速度相對快

5,減小網絡之間數據傳輸,節省開銷

2、存儲過程變量

1,存儲過程當中的變量

需求:編寫存儲過程,使用變量取empno=7369的用戶名

Delimiter $$;
Create procedure testa();
BEGIN 
	DECLARE my_uname varchar(32) default ""; -- 定義變量my_uname
 SET my_uname='smith'; -- 爲變量my_uname賦值
 -- 查詢empno=7369的用戶名,並將值賦給my_uname
 select ename into my_uname from emp where empno=7369; -- 爲變量賦值
 select my_uname;-- 返回my_uname的值
END;
$$;
Delimiter ;

特色:

1,變量的聲明使用declare,一句declare只聲明一個變量,變量必須先聲明後使用。

2,變量具備數據類型和長度,與mysql的SQL數據類型保持一致,還能指定默認值、字符集和排序規則等。

3,變量能夠經過set來賦值,也能夠經過select into的方式賦值。

4,變量須要返回,可使用select語句,如:select 變量名

2,存儲過程變量應用示例

需求:統計表emp、dept的行數和emp表中最先,最晚的入職日期。

Delimiter $$;
Create procedure stats_emp();
BEGIN
-- 統計emp和dept表中的記錄數
 BEGIN
 DECLARE emp_sum int default 0;
 DECLARE dept_sum int default 0;
 select count(*) into emp_sum from emp; 
 select count(*) into dept_sum from dept; 
 select emp_sum,dept_sum;
 END;
-- 統計最先、最晚入職日期
 BEGIN
 DECLARE max_time TIMESTAMP ;
 DECLARE min_time TIMESTAMP;
 select max(hiredate),min(hiredate) into max_time,min_time from emp;
 select max_time,min_time; 
	END;
END
$$;
Delimiter ;

3、存儲過程的參數

1,存儲過程的傳入參數IN

需求:編寫存儲過程,傳入empno,返回該用戶的ename.

Delimiter $$;
Create procedure test_param(IN my_empno int);
--------
BEGIN
 DECLARE my_ename varchar(32) default '';
 select ename into my_ename from emp where empno=my_empno;
 select my_ename;
END;
$$
Delimiter ;
-- 調用
Call test_param(7369);

提示:

1,傳入參數:類型爲IN,表示該參數的值必須在調用存儲過程時指定,若是不顯示指定爲IN,那麼默認就是IN類型。

2,IN類型參數通常只用於傳入,在調用存儲過程當中通常不做修改和返回。

3,若是調用存儲過程當中須要修改和返回值,可使用OUT類型參數。

2,存儲過程的傳出參數OUT

需求:調用存儲過程時,傳入empno,返回該用戶的ename。

Delimiter $$;
create procedure test_param(IN my_empno int,OUT my_ename varcahr(32));
--------
BEGIN
 select ename into my_ename from emp where empno=my_empno;
 select my_ename;
END;
$$
Delimiter ;
-- 調用
Set @uname=’’;
Call test_param_out(7369,@uname);

提示:

1,傳出參數:在調用存儲過程當中,能夠改變其值,並可返回。

2,OUT是傳出參數,不能用於傳入參數值。

3,調用存儲過程時,OUT參數也須要指定,但必須是變量,不能是常量。

4,若是既須要傳入,同時又須要傳出,則可使用INOUT類型參數。

3,存儲過程的可變參數INOUT

需求:調用存儲過程時,參數my_empno和my_ename,既是傳入,也是傳出參數。

Delimiter $$;
create procedure test_param_inout(INOUT my_empno int,INOUT my_ename varchar(32));
BEGIN
 set my_empno=7369;
 set my_ename="smith";
 
 select ename,empno into my_ename,my_empno from emp where empno=my_empno;
END;
$$
Delimiter ;
-- 調用
set @uname:='';
set @empno:=7399;
call test_param_inout(@empno,@uname);
select @empno,@uname;

特色:

1,可變變量INOUT,調用時可傳入值,在調用過程當中,能夠修改其值,同時也能夠返回值。

2,INOUT 參數集合了IN和OUT類型參數的功能

3,INOUT調用時傳入的是變量,而不是常量

4、存儲過程條件語句

1,存儲過程的條件語句

需求:編寫存儲過程,若是用戶empno是偶數則給出ename,其餘狀況只返回empno.

Delimiter $$;
create procedure test_if(IN my_empno int);
BEGIN
	DECLARE my_ename VARCHAR(32) default ''; 
 if(my_empno %2=0) then 
 select ename into my_ename from emp where empno=my_empno;
	select my_ename;
 else 
 select my_empno;
 end if;
END;
$$
Delimiter ;
-- 調用
call test_if(7369);

特色:

1,條件語句最基本結構: if() then ... else ... end if;

2,if判斷返回邏輯真或者假,表達式能夠是任意返回真或假的表達式

2,存儲過程的條件語句應用示例

需求:根據用戶傳入的empno參數判斷:

(1)若是用戶sal小於2000,則給用戶加薪200

(2)若是用戶sal小於1000,則給用戶加薪500

(3)其餘狀況加薪100

Delimiter $$;
create procedure test_if_else(IN my_empno int);
BEGIN
	DECLARE my_sal int default 0;
 select sal into my_sal from emp where empno=my_empno;
 if(my_sal<1000) then 
 update emp set sal=sal+500 where empno=my_empno; 
 ELSEIF(my_sal<2000)
 then update emp set sal=sal+200 where empno=my_empno; 
 else update emp set sal=sal+100 where empno=my_empno; 
 end if;
END;
$$
Delimiter ;
-- 調用
call test_if_else(7369);

特色:

多條件判斷結構:

If()

Then

...

Else if()

Then

...

Else

...

End if;

5、存儲過程循環語句

1,while循環

需求:使用循環語句,向表emp中插入10條empno連續的記錄。

Delimiter $$;
create procedure test_while();
BEGIN
 DECLARE i int default 0;
 while(i<10) DO
 BEGIN
 set i=i+1;
 insert into acc(id) values(i);
 END;
 END WHILE;
 
END;
$$
Delimiter ;
-- 調用
call test_while();

特色:

1,while語句最基本結構: while() do begin ... end end while;;

2,while判斷返回邏輯真或者假,表達式能夠是任意返回真或假的表達式

2,repeat循環語句

需求:使用repeat循環向表acc插入10條id連續的記錄

Delimiter $$;
create procedure test_repeat();
BEGIN
 DECLARE i int default 100;
 REPEAT
 BEGIN
 set i=i+1;
 insert into acc(id) values(i);
 END;
 UNTIL i>=110
 END REPEAT;
END;
$$
Delimiter ;
-- 調用
call test_repeat();

特色:

1,repeat語句最基本結構: repeat begin ... end until end repeat;;

2,while判斷返回邏輯真或者假,表達式能夠是任意返回真或假的表達式

6、存儲過程遊標的使用

1,什麼是遊標

需求:編寫存儲過程,使用遊標,把uid爲偶數的記錄逐一更新用戶名。

Delimiter $$;
create procedure test_cursor();
BEGIN
 DECLARE stopflag INT DEFAULT 0; -- 遊標中止的標記 0:未中止 1:已中止
 DECLARE my_uname VARCHAR(32) default ''; -- 存儲查詢出的用戶名
 DECLARE uname_cursor CURSOR for select uname from acc where uid%2=0; -- 定義遊標uname_cursor,並指定結果集
 DECLARE CONTINUE HANDLER for NOT found set stopflag=1; -- 遊標結束後stopflag設置爲1
	 open uname_cursor; -- 打開遊標
 FETCH uname_cursor into my_uname; -- -- 遊標向前走一步,取出一條記錄放到my_uname中my_uname
 WHILE(stopflag=0)
 DO
 BEGIN
 update acc set uname=CONCAT(my_uname,"_cur") where uname=my_uname;
 FETCH uname_cursor into my_uname; 
 END;
 end WHILE;
 close uname_cursor;
END;
$$
Delimiter ;
-- 調用
call test_repeat();

特色:

declare uname_cur Cursor for select uname from acc where uid%2=0;

1,遊標是保存查詢結果的臨時內存區域

2,遊標變量uname_cur保存了查詢的臨時結果,實際上就是查詢結果集

Declare continue handler for not found set stopflag=1;

3,當遊標變量中保存的結果都查詢一遍(遍歷),到達結尾,把變量stopflag設爲1。

4, FETCH uname_cursor into my_uname; -- 遊標向前走一步,取出一條記錄放到my_uname中

Mysql函數

1、一個簡單函數

需求:編寫函數,傳入一個uid,返回用戶的uname

Delimiter $$;
 CREATE FUNCTION f01_simple(my_uid int) RETURNS varchar(32) CHARSET utf8
	BEGIN
 DECLARE my_uname varchar(32) default '';
 select uname into my_uname from acc where uid=my_uid;
	RETURN my_uname;
END
$$
Delimiter ;
-- 調用
Select f01_simple(2);

特色:

1,建立函數使用 create function 函數名(參數) return 返回值

2,函數體放在begin和end之間

3,return 指定函數的返回值

4,函數調用: select 函數名(實參);

2、自定義函數綜合應用示例

1,自定義函數示例01

需求:輸入用戶uid,得到accountid,uid,uname組合的uuid值,做爲用戶的惟一標識。

Delimiter $$;
 CREATE FUNCTION test_uuid(my_uid int) RETURNS varchar(32) CHARSET utf8
BEGIN
 DECLARE uuid varchar(32) default '';
 select CONCAT(accountid,"_",uid,"_",uname) INTO uuid from acc where uid=my_uid;
 RETURN uuid;
END
$$;
Delimiter ;
-- 調用
Select test_uuid(2);

2,自定義函數示例02

需求:輸入用戶uid,計算該uid所在賬號下的全部訂單的總價。

觸發器trigger

場景:一般用 於審計、業務數據完整性

1,什麼是觸發器

需求:處於審計目的,當有人往表users插入一條記錄時,把插入的uid,uname和動做及操做時間記錄下來。

Delimiter $$;
CREATE TRIGGER `tr_users_insert` AFTER INSERT ON `users` 
FOR EACH ROW 
	BEGIN
-- New 插入後當前的用戶信息
 insert into oplog(uid,uname,action,optime) VALUES(NEW.uid,NEW.uname,'insert',now());
END;
$$;
Delimiter ;

特色:

1,建立觸發器使用create trigger 觸發器名稱。

2,何時觸發? after insert on users,處理after還有before ,是在對錶操做以前(before)或者以後(after)觸發動做的。

3,對什麼操做事件觸發?After insert on users,操做時間包括insert,update,delete

4,對什麼表觸發? after insert on users

5,影響的範圍?For each row

觸發器:與函數、存儲過程同樣,觸發器是一種對象,它能根據對錶的操做事件,觸發一些動做,這些動做能夠是insert,update,delete等修改操做。

2,生產環境觸發器實例

需求:處於審計目的,當刪除users表時,記錄刪除前該記錄的主要字段值。

Delimiter $$;
CREATE TRIGGER `tr_user_delete` BEFORE DELETE ON `users` FOR EACH ROW begin 
-- OLD對字段表更新前的數據 
 insert into oplog(uid,uname,action,optime,old_value) values(OLD.uid,OLD.uname,"delete",now(),OLD.regtime);
END;
$$;
Delimiter ;
相關文章
相關標籤/搜索