0

好的,让我介绍一下主题:我有两个不同的员工表,它们具有不同的字段,我想将它们合并到一个表中。但我想保留旧表并不时执行我的程序来更新我的新表。

这是我到目前为止得到的代码,它在几个小时的错误后终于编译了,但是当我执行我的程序时,我收到消息“未找到条目”。

create type Employee_t as object (
    name varchar2(60),
    birthdate date,
    functions varchar2(40),
    monthly_income number,
    gender number,
    Employeennr number
);

create table Employee of Employee_t (Employeennr primary key);

create type Worker_T as object (
    name varchar2(30),
    firstname varchar2(30),
    birth_month varchar2(5),
    incomePerHour number
);

create table Worker of Worker_T;

create type Personal_T as object (
    personalnr number,
    name varchar2(30),
    firstname varchar2(30),
    age number,
    gender number,
    function_code number,
    incomePerYear number
);

create table Personal of Personal_T (personalnr primary key);

create type PersonalnrTagging_T as object (
    personalnr number,
    Employeennr number
);

create table PersonalnrTagging of PersonalnrTagging_T

create type Function_codes_T as object (
    code number,
    functions varchar2(40)
);

create table Function_codes of Function_codes_T;

create type Gender_T as object (
    gender number,
    firstname varchar(30)
);

create table Gender of Gender_T;

create sequence Personalnr_Seq start with 1;

create function DateToAge (birthdate date)
    return number
    is
        begin
            return floor(months_between(sysdate, birthdate) / 12);
        end;

create function StringToAge (birth_month varchar2)
    return number
    is
        begin
            return floor(months_between(sysdate, to_date(birth_month, 'MM.YY')) / 12);
        end;

create function GetSurname (name varchar2)
    return varchar2
    is
        pos number;
        begin
            pos := instr(name, ',', 1, 1);
            if (pos > 0) then
                return substr(name, 0, pos);
            end if;
            pos := instr(name, ' ', 1, 1);
            return substr(name, pos + 1);
        end;

create function GetFirstname (name varchar2)
    return varchar2
    is
        pos number;
        begin
            pos := instr(name, ',', 1, 1);
            if (pos > 0) then
                return substr(name, pos + 1);
            end if;
            pos := instr(name, ' ', 1, 1);
            return substr(name, 0, pos);
        end;

create procedure InsertTables
    is
        cursor employeer
            is select * from Employee;
        cursor worker
            is select * from Worker;
        anr number;
        ann varchar2(30);
        id number;
        bcode number;
        persnr number;
        gendr number;
        begin
            for a in employeer
            loop
                select Employeennr into anr from PersonalnrTagging where Employeennr = a.Employeennr;
                if (anr is null) then
                    select Personalnr_Seq.nextval into id from dual;
                    select code into bcode from Function_codes where functions = a.functions;
                    insert into Personal
                    values  (id, GetSurname(a.name), GetFirstname(a.name), DateToAge(a.birthdate), a.gender,
                            bcode, a.monthly_income * 12);
                    insert into PersonalnrTagging values (id, a.Employeennr);
                else
                    select code into bcode from Function_codes where functions = a.functions;
                    select personalnr into persnr from PersonalnrTagging where Employeennr = a.Employeennr;
                    update Personal
                    set     name = GetSurname(a.name), firstname = GetFirstname(a.name), age = DateToAge(a.birthdate),gender = a.gender,
                            function_code = bcode, incomePerYear = a.monthly_income * 12
                    where
                            personalnr = persnr;
                end if;
            end loop;
            for b in worker
            loop
                select name into ann from Personal where name = b.name and firstname = b.firstname;
                if (ann is null) then
                    select Personalnr_Seq.nextval into persnr from dual;
                    select gender into gendr from Gender where firstname = b.firstname;
                    select code into bcode from Function_codes where functions = 'Worker';
                    insert into Personal values (persnr, b.name, b.firstname, StringToAge(b.birth_month), gendr, bcode, b.incomePerHour * 40 * 49);
                else
                    select gender into gendr from Gender where firstname = b.firstname;
                    select code into bcode from Function_codes where functions = 'Worker';
                    select personalnr into persnr from Personal where name = b.name and firstname = b.firstname;
                    update Personal
                    set name = b.name, firstname = b.firstname, age = StringToAge(b.birth_month), gender = gendr,
                            function_code = bcode, incomePerYear = b.incomePerHour * 40 * 49
                    where 
                            personalnr = persnr;
                end if;
            end loop;
        end;



insert into Gender values (1, 'Hans');
insert into Gender values (2, 'Petra');
insert into Gender values (0, 'Vali');

insert into Function_codes values (01, 'Professor');

insert into Worker values ('Schulz', 'Hans', '07.87', 1);
insert into Worker values ('Schulz', 'Vali', '11.23', 2);

insert into Employee values ('Herbst, Petra', to_date('76/01/23', 'YY/MM/DD'), 'Professor', 324, 2, 20);

有人看到我犯的错误吗?或者知道问题可能是什么?

4

1 回答 1

2

错误来自您的SELECT INTO陈述

如果 Select into 没有找到结果,您必须用异常捕获它(您不能只测试您的变量是否为空)。

所以我在你的SELECT INTO陈述周围添加了类似的块

BEGIN
 SELECT INTO xxx
EXCEPTION WHEN NO_DATA_FOUND THEN
 bla bla
END;

所以我用很少的 dbms_output 来纠正你的程序(为了缩短日志)

现在我们开始 :

create or replace
procedure InsertTables
    is
        cursor employeer
            is select name, birthdate, gender, monthly_income, Employeennr, functions from Employee;
        cursor worker
            is select * from Worker;
        anr number;
        ann varchar2(30);
        ide number;
        bcode number;
        persnr number;
        gendr number;
        begin
            for a in employeer
            loop
                begin
                  select Employeennr 
                  into anr 
                  from PersonalnrTagging 
                  where Employeennr = a.Employeennr;
                exception when no_data_found then 
                    select Personalnr_Seq.nextval into ide from dual;
                    select code into bcode from Function_codes where functions = a.functions;
                    insert into Personal
                    values  (ide, GetSurname(a.name), GetFirstname(a.name), DateToAge(a.birthdate), a.gender,
                            bcode, a.monthly_income * 12);
                    insert into PersonalnrTagging values (ide, a.Employeennr);
                end;

                select code into bcode from Function_codes where functions = a.functions;
                select personalnr into persnr from PersonalnrTagging where Employeennr = a.Employeennr;
                update Personal
                set     name = GetSurname(a.name), firstname = GetFirstname(a.name), age = DateToAge(a.birthdate),gender = a.gender,
                            function_code = bcode, incomePerYear = a.monthly_income * 12
                where personalnr = persnr;
            end loop;
            for b in worker
            loop
                gendr:=null;
                bcode:=null;
                persnr:=null;
                begin
                select gender into gendr from Gender where firstname = b.firstname;
                    exception when no_data_found then
                      dbms_output.put_line('no Gender for firstName '||b.firstname);
                    end;
                    begin
                    select code into bcode from Function_codes where functions = 'Worker';
                    exception when no_data_found then
                      dbms_output.put_line('no code for function Worker');
                    end;
                begin
                    select name into ann from Personal where name = b.name and firstname = b.firstname;
                exception when no_data_found then

                    select Personalnr_Seq.nextval into persnr from dual;


                    if gendr is null or bcode is null then
                     dbms_output.put_line('error in inserting');
                    else
                    insert into Personal values (persnr, b.name, b.firstname, StringToAge(b.birth_month), gendr, bcode, b.incomePerHour * 40 * 49);
                    end if;
                end;
                    begin
                    select personalnr into persnr from Personal where name = b.name and firstname = b.firstname;
                    exception when no_data_found then
                     dbms_output.put_line('no persnr with name '||b.name||' and firstname '|| b.firstname);
                    end;
                    if (gendr is null or bcode is null or persnr is null) then
                       dbms_output.put_line('error in updating');
                    else
                    update Personal
                    set name = b.name, firstname = b.firstname, age = StringToAge(b.birth_month), gender = gendr,
                            function_code = bcode, incomePerYear = b.incomePerHour * 40 * 49
                    where 
                            personalnr = persnr;
                    end if;
            end loop;
        end;

现在我们可以安全地运行它,并收到一些错误消息(我们的消息,不是 Oracle 的):

no code for function Worker
error in inserting
no persnr with name Schulz and firstname Hans
error in updating
no code for function Worker
error in inserting
no persnr with name Schulz and firstname Vali
error in updating

我们看到您忘记在 Function_codes 表中插入一个 Worker 函数。

如果你只是这样做

insert into Function_codes values (02, 'Worker');

你没有任何错误。

您会在个人表格中看到所有结果:

...但你的人有年龄

-64 -75 -11

认为在 varchar (87 = 2087, 76 = 2076) 中插入日期缩短时仍然存在问题!

于 2013-01-10T15:34:54.467 回答