一.变量
1.系统变量 global session
2.用户自定义变量
1.不用提前声明,使用时直接'' @变量名 ''
2.set @name='lisi';
set 字段名 into @name from 表名
3.局部变量
1.需要用declare声明
2.declare 变量名 类型
3.set 变量名=值
二.触发器
.1函数
DELIMITER $$USE `shujuku`$$DROP FUNCTION IF EXISTS `PysxCx`$$CREATE DEFINER=`root`@`localhost` FUNCTION `PysxCx`(zw VARCHAR(20)) RETURNS VARCHAR(20) CHARSET utf8mb4READS SQL DATA
BEGINSET @pysx='';SET @l=CHAR_LENGTH(zw);SET @i=1;WHILE (@i<=@l) DOSELECT jp INTO @jp FROM hzpyb WHERE hz=SUBSTR(zw,@i,1);SET @pysx=CONCAT(@pysx,@jp);SET @i=@i+1;END WHILE; RETURN @pysx;END$$DELIMITER ;
触发器1
DELIMITER $$USE `shujuku`$$DROP TRIGGER `Update_mcsx_before_insert_goods`$$CREATETRIGGER `Update_mcsx_before_insert_goods` BEFORE INSERT ON `goods` FOR EACH ROW BEGIN SET new.abbreviations=pysxcx(new.gname);
END;
$$DELIMITER ;
触发器2
DELIMITER $$USE `shujuku`$$DROP TRIGGER `Update_mcsx_before_update_goods_gname`$$CREATETRIGGER `Update_mcsx_before_update_goods_gname` BEFORE UPDATE ON `goods` FOR EACH ROW BEGIN IF new.gname<>old.gname THEN SET new.abbreviations=pysxcx(new.gname); END IF;
END;
$$DELIMITER ;
2超市购买物品
goodswh
DELIMITER $$USE `shujuku`$$DROP PROCEDURE IF EXISTS `goodswh`$$CREATE DEFINER=`root`@`localhost` PROCEDURE `goodswh`(gid INT,gname VARCHAR(20),unit VARCHAR(20),barcode VARCHAR(20),retail_Price DECIMAL(10,2),promotional_Price DECIMAL(10,2),STATUS TINYINT)
BEGINIF gid=0 THENINSERT INTO goods(gname,unit,barcode,retail_Price,promotional_Price,STATUS) VALUES (gname,unit,barcode,retail_Price,promotional_Price,STATUS);ELSEIF gid>0 THENUPDATE goods SET goods.gname=gname, goods.unit=unit, goods.barcode=barcode, goods.retail_Price=retail_Price, goods.promotional_Price=promotional_Price, goods.STATUS=STATUS WHERE goods.gid=gid;ELSEDELETE FROM goods WHERE goods.gid=-gid;END IF;END$$DELIMITER ;
goodscx
DELIMITER $$USE `shujuku`$$DROP PROCEDURE IF EXISTS `goodscx`$$CREATE DEFINER=`root`@`localhost` PROCEDURE `goodscx`(gid INT)
BEGINIF gid=0 THENSELECT * FROM goods;ELSESELECT * FROM goods WHERE goods.gid=gid;END IF;
END$$DELIMITER ;
删除触发器
DELIMITER $$USE `shujuku`$$DROP TRIGGER /*!50032 IF EXISTS */ `delete_from_stock_after_delete_goods`$$CREATE/*!50017 DEFINER = 'root'@'localhost' */TRIGGER `delete_from_stock_after_delete_goods` BEFORE DELETE ON `goods` FOR EACH ROW BEGIN DELETE FROM stock WHERE gid=old.gid;
END;
$$DELIMITER ;
11.超市存储过程
DELIMITER $$USE `shujuku`$$DROP PROCEDURE IF EXISTS `Xsjlcp_new`$$CREATE DEFINER=`root`@`localhost` PROCEDURE `Xsjlcp_new`(cashierid INT, uid INT, payment TINYINT, xsmx VARCHAR(8000))
BEGINDECLARE amount_money DECIMAL(18,3);DECLARE actual_money DECIMAL(18,3);DECLARE discount_money DECIMAL(18,3);-- 如果存在名为 lsb 的表,则删除它DROP TEMPORARY TABLE IF EXISTS lsb;-- 创建临时表 lsb,包含 gid 和 xssl 两个字段CREATE TEMPORARY TABLE lsb (gid INT, xssl NUMERIC(18,3));-- 使用 WHILE 循环解析 xsmx 中的数据并插入到 lsb 表中WHILE (xsmx > '') DOSET @k = POSITION(',' IN xsmx);SET @gid = LEFT(xsmx, @k - 1);SET xsmx = SUBSTR(xsmx, @k + 1);SET @k = POSITION(',' IN xsmx);SET @xssl = LEFT(xsmx, @k - 1);INSERT INTO lsb(gid, xssl) VALUES(@gid, @xssl);SET xsmx = SUBSTR(xsmx, @k + 1);END WHILE;-- 计算总金额和实际金额SELECT SUM(xssl * retail_Price) INTO amount_money FROM lsb, goods WHERE lsb.gid = goods.gid;SELECT SUM(xssl * promotional_Price) INTO actual_money FROM lsb, goods WHERE lsb.gid = goods.gid;SET discount_money = amount_money - actual_money;-- 插入收银记录到 cashaccount 表INSERT INTO cashaccount(cashierid, uid, payment, amount_money, actual_money, discount_money)VALUES (cashierid, uid, payment, amount_money, actual_money, discount_money);-- 插入销售明细到 cashaccount_detail 表INSERT INTO cashaccount_detail(cashaccountid, gid, salesquantity, retailprice, promotionalprice)SELECT LAST_INSERT_ID(), lsb.gid, xssl, retail_Price, promotional_Price FROM lsb, goods WHERE lsb.gid = goods.gid;-- 更新库存UPDATE stock s JOIN lsb ON s.gid = lsb.gid SET s.quantity = s.quantity - lsb.xssl;-- 如果 uid 大于等于 10000,则更新用户的卡余额和积分IF uid >= 10000 THENUPDATE `user` SET card_balance = card_balance - actual_money, points = points + FLOOR(actual_money)WHERE uid = uid;END IF;-- 删除临时表 lsbDROP TEMPORARY TABLE IF EXISTS lsb;END$$DELIMITER ;
3.xkglxt
1.实现学生表的插入,需要判断当前学号学生是否存在
DELIMITER $$USE `myspj`$$DROP PROCEDURE IF EXISTS `insert_Student`$$CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_Student`(IN Studentid INT ,IN Studentname VARCHAR(10))
BEGINDECLARE StudentExists INT ;SELECT COUNT(*) INTO StudentExistsFROM Student WHERE id=Studentid;IF StudentExists > 0 THEN SELECT '学号存在,学生信息插入失败' ;ELSEINSERT INTO Student(id,`name`) VALUES (Studentid,Studentname);SELECT '学生信息插入成功';END IF;END$$DELIMITER ;
2.实现选课表的插入,需要判断当前课程id和学生id是否存在
DELIMITER $$USE `myspj`$$DROP PROCEDURE IF EXISTS `insert_xuanke`$$CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_xuanke`(IN _xid INT, IN _id INT, IN _kid INT, IN _chengji INT)
BEGIN DECLARE studentExists INT DEFAULT 0; DECLARE courseExists INT DEFAULT 0; SELECT COUNT(*) INTO studentExists FROM Student WHERE id = _id; IF studentExists = 0 THEN SELECT '学生id不存在' AS result; END IF; SELECT COUNT(*) INTO courseExists FROM kecheng WHERE kid = _kid; IF courseExists = 0 THEN SELECT '课程id不存在' AS result; ELSE -- 检查学生是否已经选了这门课程 IF NOT EXISTS (SELECT 1 FROM xuanke WHERE kid = _kid AND id = _id) THEN INSERT INTO xuanke (xid, id, kid, chengji) VALUES (_xid, _id, _kid, _chengji); SELECT '插入成功' AS result; ELSE SELECT '学生已选该课程'; END IF; END IF;
END$$DELIMITER ;
4.订单延期
将顾客表上余额不足1000元的,将订单日期延后10天
UPDATE orders
SET DATE = DATE_ADD(DATE, INTERVAL 10 DAY)
WHERE orders.gid IN (SELECT gidFROM customersWHERE balance < 1000
);
将商品表中没有顾客订购的商品信息删除
DELETE FROM goods
WHERE goods.`sid` NOT IN (
SELECT DISTINCT orders.`sid` FROM orders
)
5.建立索引
CREATE INDEX sname ON `student`(`studentname`);CREATE INDEX qanswer ON `questionbank`(`questionAnswer`(1000));
6.当插入、删除试题时,修改章节表的试题数量
DELIMITER $$CREATETRIGGER `network_course`.`insert_from_questionbank_after_add_chapter` AFTER UPDATEON `network_course`.`questionbank`FOR EACH ROW BEGINUPDATE chapter SET `questioncount`=`questioncount`+1WHERE `chapterid`=new.`chapterid`;END$$DELIMITER ;
7.写出插入一条学生数据的存储过程
DELIMITER $$CREATEPROCEDURE `network_course`.`insert_one_student`(IN snum VARCHAR(20),IN sname VARCHAR(20),IN spw VARCHAR(20),IN cid INT)BEGINDECLARE count1 INT;SELECT COUNT(*) INTO count1FROM student WHERE `studentnum`=snum;IF count1=0 THENINSERT INTO student(`studentnum`,`studentname`,`studentpw`,`classid`)VALUES(snum,sname,spw,cid);END IF;END$$DELIMITER ;
8.写出一次插入多条学生数据的存储过程
- 学生数据的格式为:
“学号1,姓名1,密码1,班级号1;学号2,姓名2,密码2,班级号2;”
例如:
"201451080102,张三,NULL,1;201451080103,李四,NULL,1;"
CALL insert_many_student("221451080608,张1,NULL,1;221451080609,李1,NULL,1;");
CAST( 字符串 AS SIGNED); 将字符串类型的数字转化为数字类型的数字
在MySQL中,MID()函数用于返回一个字符串中从指定位置开始的指定长度的子字符串。其语法为:
MID(str, start, length)
str为要从中提取子字符串的原始字符串。
start为要开始提取子字符串的位置(位置从1开始)。
length为要提取的子字符串的长度
在MySQL中,LOCATE()函数用于在一个字符串中查找子字符串,并返回子字符串第一次出现的位置。其语法为:
LOCATE(substring, string, start)
substring为要查找的子字符串。
string为要在其中查找子字符串的原始字符串。
start为可选参数,表示从原始字符串的某个位置开始查找。如果不指定start,则默认从字符串的第一个字符开始查找。
DELIMITER $$CREATEPROCEDURE `network_course`.`insert_many_student`(IN stustr VARCHAR(5000))BEGINDECLARE str1 VARCHAR(200);DECLARE num0 VARCHAR(20);DECLARE name0 VARCHAR(20);DECLARE PW0 VARCHAR(20);DECLARE classid0 INT ;DECLARE flag INT;WHILE stustr>' ' DOSET str1 = MID(stustr,1,LOCATE(';',stustr)-1);SET num0 = MID(str1,1,LOCATE(',',str1)-1);SET str1 = MID(str1,LOCATE(',',str1)+1);SET name0 = MID(str1,1,LOCATE(',',str1)-1);SET str1 = MID(str1,LOCATE(',',str1)+1);SET pw0 = MID(str1,1,LOCATE(',',str1)-1);SET classid0 =CAST(MID(str1,LOCATE(',',str1)+1) AS SIGNED);CALL `insert_one_student`(num0,name0,pw0,classid0);SET stustr= MID(stustr,LOCATE(';',stustr)+1);END WHILE ;END$$DELIMITER ;
9.生成学生试卷
输入参数:学生帐号,按照规则生成学生试卷总表以及试卷明细表
DELIMITER $$USE `network_course`$$DROP PROCEDURE IF EXISTS `insert_exam`$$CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_exam`(IN studentid0 INT)
BEGINDECLARE examid0 INT;DECLARE fromc0 INT;DECLARE toc0 INT;DECLARE type0 INT;DECLARE diff0 INT;DECLARE c0 INT;DECLARE done INT DEFAULT FALSE;DECLARE cur CURSOR FOR SELECT `fromchapterid`,`tochapterid`,`type`, `difficulty`, `count`FROM exam_rule ORDER BY exam_ruleid;DECLARE CONTINUE HANDLER FOR NOT FOUND SET done= TRUE;SELECT COUNT(*)INTO c0 FROM exam WHERE studentid=studentid0;IF c0=0 THENINSERT INTO exam(studentid,state,score)VALUES(studentid0,0,0);SELECT LAST_INSERT_ID()INTO examid0;OPEN cur;FETCH cur INTO fromc0,toc0,type0,diff0,c0;WHILE(NOT done) DO INSERT INTO exam_detail(examid,questionid,answer ,grade)SELECT examid0 AS examid,questionid,'' AS answer,0 AS gradeFROM questionbank WHERE chapterid>=fromc0 AND chapterid<=toc0AND `type`=type0 AND difficulty=diff0 ORDER BY RAND() LIMIT c0;FETCH cur INTO fromc0,toc0,type0,diff0,c0;END WHILE;CLOSE cur;END IF;END$$DELIMITER ;
10.生成班级试卷
输入参数:班级ID,按照规则生成班级所有学生的试卷总表以及试卷明细表
DELIMITER $$CREATEPROCEDURE `network_course`.`insert_exam0`(IN classid0 INT)BEGINDECLARE examid0 INT;DECLARE stuid0 INT;DECLARE done INT DEFAULT FALSE;DECLARE cur CURSOR FOR SELECT studentid FROM studentWHERE classid=classid0;DECLARE CONTINUE HANDLER FOR NOT FOUND SET done= TRUE;OPEN cur;FETCH cur INTO stuid0;WHILE(NOT done)DOCALL insert_exam (stuid0);FETCH cur INTO stuid0;END WHILE;CLOSE cur;END$$DELIMITER ;