mysql 存儲過程 觸發器 初探

什麼是存儲過程?

即是可以編寫邏輯的sql,如判斷,循環等,,

有什麼好處?

設想我們要插入100條數據,在存儲過程中循環和批量操作相比,肯定存儲過程效率高咯…另外存儲過程的運行速度是很快的,你發送幾條sql到數據庫和發送一條執行命令到數據庫,肯定執行命令的速度快多啦!!

壞處

移植性,,,不好吧。。。

我測試用的數據庫結構

/*
Navicat MySQL Data Transfer

Source Server         : localhost
Source Server Version : 50717
Source Host           : localhost:3306
Source Database       : pro_test

Target Server Type    : MYSQL
Target Server Version : 50717
File Encoding         : 65001

Date: 2018-02-04 20:59:23
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for t_interest
-- ----------------------------
DROP TABLE IF EXISTS `t_interest`;
CREATE TABLE `t_interest` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `s_id` int(11) DEFAULT NULL COMMENT '學生id',
  `name` varchar(32) DEFAULT NULL COMMENT '興趣名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Table structure for t_log
-- ----------------------------
DROP TABLE IF EXISTS `t_log`;
CREATE TABLE `t_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `content` varchar(32) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Table structure for t_student
-- ----------------------------
DROP TABLE IF EXISTS `t_student`;
CREATE TABLE `t_student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Procedure structure for ifAndWhileTest
-- ----------------------------
DROP PROCEDURE IF EXISTS `ifAndWhileTest`;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `ifAndWhileTest`(in c CHAR, in num int, out result int)
begin 
declare i int default 0;
declare sum int default 0;
IF c = '1'
THEN
while i <= num DO
set sum = sum + i;
set i = i + 1;
END WHILE;
set result = sum; 
ELSE
set result = 0;
END IF;
end
;;
DELIMITER ;

-- ----------------------------
-- Procedure structure for inTest
-- ----------------------------
DROP PROCEDURE IF EXISTS `inTest`;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `inTest`(in a int)
begin 
set a = 6;
select a;
end
;;
DELIMITER ;

-- ----------------------------
-- Procedure structure for outTest
-- ----------------------------
DROP PROCEDURE IF EXISTS `outTest`;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `outTest`(out a int)
begin 
set a = 6;
select a;
end
;;
DELIMITER ;

-- ----------------------------
-- Procedure structure for saveStudent
-- ----------------------------
DROP PROCEDURE IF EXISTS `saveStudent`;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `saveStudent`(in stuName varchar(32), in interestName varchar(32))
begin 
declare stuId int;
insert into t_student(name) values(stuName);
select max(id) into stuId from t_student;
insert into t_interest(s_id, name) values(stuId, interestName);  
end
;;
DELIMITER ;
DROP TRIGGER IF EXISTS `toStudentAdd`;
DELIMITER ;;
CREATE TRIGGER `toStudentAdd` AFTER INSERT ON `t_student` FOR EACH ROW begin 
insert into t_log(content, create_time) values(concat('學生表插入了一條記錄,id是', new.id), now());
end
;;
DELIMITER ;
DROP TRIGGER IF EXISTS `toStudentUpdate`;
DELIMITER ;;
CREATE TRIGGER `toStudentUpdate` AFTER UPDATE ON `t_student` FOR EACH ROW begin 
insert into t_log(content, create_time) values(concat('學生表更新了一條記錄,原id是', old.id, '更新後的名字是', new.name), now());
end
;;
DELIMITER ;

定義

delimiter (你自定義的符號)
create procedure 存儲過程名稱(參數) 
begin 
..............過程
end (你自定義的符號)

關於參數

  1. in參數,只能作爲接受的值,無法修改
  2. out參數,可以修改,不能接受
  3. inout參數,結合兩者。。

    eg:

delimiter //
create procedure inTest(in a int) 
begin 
set a = 6;
select a;
end //

-- 以下是調用
set  @s = 1;
call inTest(@s);
select @s;

-- ------------------上面的存儲過程中修改a的值爲6並輸出後,我們再次查詢 @s 的值發現還是1,並沒有變

delimiter //
create procedure outTest(out a int) 
begin 
set a = 6;
select a;
end //

set  @f = 1;
call outTest(@f);
select @f;
-- ------------------上面的存儲過程中修改a的值爲6並輸出後,我們再次查詢 @f 的值發現變成6

關於選擇結構和循環

直接看代碼吧:

-- 輸入一個字母和一個數字,如果字母是a,計算0-這個數字的和並返回,否則返回0
delimiter //
create procedure ifAndWhileTest(in c CHAR, in num int, out result int) 
begin 
declare i int default 0;
declare sum int default 0;
-- declare是定義局部變量,貌似只能定義在代碼最前端。。我試的時候是這樣
IF c = '1'
THEN
while i <= num DO
set sum = sum + i;
set i = i + 1;
END WHILE;
set result = sum; 
ELSE
set result = 0;
END IF;
end //

call ifAndWhileTest('a', 100, @r);
select @r;

實例

-- 實例,一個存儲過程,接受學生姓名和愛好,進行插入(兩張表的操作)

delimiter //
create procedure saveStudent(in stuName varchar(32), in interestName varchar(32))
begin 
declare stuId int;
insert into t_student(name) values(stuName);
select max(id) into stuId from t_student;
insert into t_interest(s_id, name) values(stuId, interestName);  
end //

call saveStudent('小肥', '曬太陽')

觸發器

就是在執行某個操作後我們希望執行操作.比如在操作學生表時記錄日誌

-- 實現觸發器,對學生進行操作時進行記錄(語法就是下面這樣)
create trigger toStudentAdd after insert on t_student for each row 
begin 
insert into t_log(content, create_time) values(concat('學生表插入了一條記錄,id是', new.id), now());
end

-- new代表新的數據,old代表舊的數據
create trigger toStudentUpdate after update on t_student for each row 
begin 
insert into t_log(content, create_time) values(concat('學生表更新了一條記錄,原id是', old.id, '更新後的名字是', new.name), now());
end

update t_student set name = '小發' where id = 4
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章