Oracle 游标实现学生学号自动生成

版权声明:@YDDUONG https://blog.csdn.net/y_dd6011/article/details/83796027

每个学生都有唯一专属的学号,现有学号格式为ABCDEFGHIJ共10位数字,其中AB表示学院编号;CD表示专业编号;EF表示年级;GH表示班级编号;IJ表示学生序号。

已知:2018年开学之际,已知每个专业的总人数和需要分配的班级数,请为每位同学分配唯一的学号。

要求:每个专业的班级序号是连续的,班内学生学号是连续。

学院编号 专业编号 班级总数 专业人数
02 03 6 187
02 03 2 71
07 08 21 632

最后生成的学号如:

0203180101

0203180102

 ~  ~  ~

0708180101

0708180102

 ~  ~  ~

drop table temp;
create table temp(
    academy_id varchar2(4) not null,
    major_id varchar2(4) not null,
    class_allnum number not null,
    student_allnum number(4) not null);

insert into temp values('02','03',6,187);
insert into temp values('02','03',2,71);
insert into temp values('07','08',21,632);
select * from temp;


--说明文档:
--1.预先建立一张原始数据表,确定每个学院的每个专业一共有多人,且要分几个班级
--2.建立带参数的过程,传入年级(如:18级,传入字符:18)
--3.参数说明:
--	cursor temp_num is select * from temp  初始化表temp的游标
--	curTemp 游标对象
--	student_num 每个班级的人数(整数),如:187人分个6班,每班31人
--	student_tempnum 每个班级的人数(小数),如:187人分个6班,每班31.16人
--		  由于oracle在数值类型转时(从小数到整数),会进行四舍五入运算,而不是取整运算,所以通过比较以上两者的数值,来判断每个班级应分配多少人
--		  如:某专业623人打算分21个班级(623/21=29.66),则初打算每班分配29,而不是30人
--	student_otherNum 多出来的学生,如:187人分个6班,多出1人
--	stud_i 循环变量:学生编号
--	class_i 循环变量:班级编号

create or replace procedure prodStudNum(year_id char)
as
cursor temp_num is select * from temp;
curTemp temp%rowtype;
student_num int;
student_tempnum number;
student_otherNum int;
stud_i int;
class_i int;
begin
delete from stud;
for curTemp in temp_num loop
	student_num:=curTemp.student_allnum/curTemp.class_allnum;
	student_tempnum:=curTemp.student_allnum/curTemp.class_allnum;
	if student_num>student_tempnum then 
		student_num:=student_num-1;
	end if;
	student_otherNum:=curTemp.student_allnum-student_num*curTemp.class_allnum;
    	for class_i in 1..curTemp.class_allnum loop
        	for stud_i in 1..Student_num loop
			if class_i<10 then 
				if stud_i<10 then
					insert into stud(sno) values(year_id||curTemp.academy_id||curTemp.major_id||'0'||class_i||'0'||stud_i);
				else
					insert into stud(sno) values(year_id||curTemp.academy_id||curTemp.major_id||'0'||class_i||stud_i);
				end if;
			else
				if stud_i<10 then
					insert into stud(sno) values(year_id||curTemp.academy_id||curTemp.major_id||class_i||'0'||stud_i);
				else
					insert into stud(sno) values(year_id||curTemp.academy_id||curTemp.major_id||class_i||stud_i);
				end if;
			end if;
        	end loop;
    	end loop;
	student_num:=student_num+1;
	for class_i in 1..curTemp.class_allnum loop
		exit when student_otherNum=0;
		if class_i<10 then 
			if student_num<10 then
				insert into stud(sno) values(year_id||curTemp.academy_id||curTemp.major_id||'0'||class_i||'0'||student_num);
			else
				insert into stud(sno) values(year_id||curTemp.academy_id||curTemp.major_id||'0'||class_i||student_num);
			end if;
		else
			if student_num<10 then
				insert into stud(sno) values(year_id||curTemp.academy_id||curTemp.major_id||class_i||'0'||student_num);
			else
				insert into stud(sno) values(year_id||curTemp.academy_id||curTemp.major_id||class_i||student_num);
			end if;
		end if;
		student_otherNum:=student_otherNum-1;
    	end loop;
end loop;
end;
/
show error
exec prodStudNum('18')
select * from stud order by sno;

猜你喜欢

转载自blog.csdn.net/y_dd6011/article/details/83796027