oracle数据库主键有规律的自动生成

前提:使用oracle10g

现在有两个表:dept 和 student

dept包括 id length=2(专业编号),name(专业名称)

student包括 id length=6(学生编号), name(学生名称), sex(性别)

要求:

student 的 id 由数据库自动生成。规则是:入学年份 + 专业编号 + 学号(学号不能大于99)

例:有一个学生,是09年入学的,专业的编号是01,学号是20,那么他的id=090120

问题就是这样,有知道如何解决的朋友请帮忙。如果没明白问题的要求,可以提出,我再追加说明。

[b]问题补充:[/b]
对 蔡华江 (架构师) 2009-12-02 提问的追加:

您所说的问题,我也不清楚如何解决,这个是我面试的一道题。

所以不清楚具体的需求,可能他们不需要做这样的关联吧。

另外,如果有知道如何做的朋友,希望你们在解答的时候把具体的代码帖上来。

因为我对oracle也是知之甚少,所以麻烦各位帮忙实现。
[b]问题补充:[/b]
hearken01 兄弟:

你好!很感谢你的回答,我按照你的代码,执行了一边。发现结果的确是按照

我的要求生成的。不过,虽然stu_id按要求生成了,可生成的值还有点问题!希

望你能继续帮我解决下,谢谢个先!

我出现的问题是这样的:

我的dept_h表里有了两条记录

dept_id:10, dept_name:物理;dept_id:20,dept_name:化学

student_h表里有两条记录

stu_id:091001,stu_name:aa; stu_id:091002,stu_name:bb

我执行select f_h('物理') from dual;得到的结果却始终是091002


这是为什么啊,我不时很理解,呵呵。还有,如果你有时间,能把你写的代

码多少加点注释好么,我很少接触oracle,所以不时很懂啊 !!

[b]问题补充:[/b]
hearken01 (中级程序员) :

谢谢你的回答!可是我把你的代码考到了我的机器上运行,结果生成的函数

有错误!然后我大概看了一下,你两次的代码差异,发现了一些不同,而我又看

不太懂,所以帖出来,向你请教:

   if stu_id<>0 then 
  if stu_id<10 then 
      stu_v := '0' || stu_id; 
    else 
    stu_v := stu_id; 
  end if; 
  else 
  stu_v := '01'; 
  end if; 

这里是不是有些重复阿。。。。。。,还有就是两个select语句出错!

我觉得会不会是咱们的表结构不一样啊,所以咱俩统一一下表结构,然后,

麻烦你再帮我调试一次好不?谢谢啦!

我定义的表结构如下(或者你吧你的表结构帖出来也行啊):

/* 专业表 */
CREATE TABLE MYDEPT(
MYID NUMBER(2,0) NOT NULL,
MYNAME VARCHAR2(40),
PRIMARY KEY ("MYID")
);

/* 学生表 */
CREATE TABLE MYSTUDENT(
MYID NUMBER(6,0) NOT NULL,
MYNAME VARCHAR2(40),
PRIMARY KEY ("MYID")
);

再试试:
create or replace function f_h (dept_name varchar2)
return varchar2 as
dept_id number;
dept_v varchar2(8);
year_num varchar2(8);
stu_id number;
stu_v varchar2(8);
result_n varchar2(16);
begin
select id into dept_id from dept_h where name=dept_name;
select to_char(sysdate,'yy') into year_num from dual;
if dept_id dept_v := '0' || dept_id;
else
dept_v := dept_id;
end if;
select substr(max(id),5,2)+1 into stu_id from student_h where substr(id,3,2)=dept_v;
if stu_id0 then
if stu_id<10 then
stu_v := '0' || stu_id;
else
stu_v := stu_id;
end if;
else
stu_v := '01';
end if;
result_n := to_char(year_num || dept_v || stu_v);
return result_n;
end;

编写一函数,把 入学年份 + 专业编号 + 学号 作为参数传进来就行了。

这只能是写程序插入的时候把id拼出来,自动生成是不可能的

dept包括 id length=2(专业编号),name(专业名称)
student包括 id length=6(学生编号), name(学生名称), sex(性别)

对这个结构有点疑问,在这里是如何表示student在那个dept呀。
如是解决这个矛盾,那么使用触发器可以方便地生成

用程序插吧 最简单最快的方法了

触发器,想怎么干就怎么干

创建函数:
create or replace function f_h (dept_name varchar2)
return varchar2 as
dept_id number;
dept_v varchar2(8);
year_num varchar2(8);
stu_id number;
stu_v varchar2(8);
result_n varchar2(16);
begin
select id into dept_id from dept_h where name=dept_name;
select to_char(sysdate,'yy') into year_num from dual;
select substr(max(id),3,4) into stu_id from student_h;
dept_v := dept_id;
stu_v := stu_id;
if stu_id<10 then
stu_v := '0' || stu_id;
end if;
if dept_id<10 then
dept_v := '0' || dept_id;
end if;
result_n := year_num || dept_v || stu_v;
return result_n;
end;
调用函数:
select f_h('软件') from dual;

select substr(max(id),3,4) into stu_id from student_h;
你把这里修改一下就可以了,我是把那个转业的最大学号取出来,然后把它
substr(max(id),3,4) 最后两位数取出来+1的,你适当修改一下就可以了,改成substr(max(id),4,5)应该没问题了。