Oracle 遊標實現學生學號自動生成
阿新 • • 發佈:2018-11-09
每個學生都有唯一專屬的學號,現有學號格式為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;