0

さて、主題を紹介しましょう。1つのテーブルにマージしたい異なるフィールドを持つ2つの異なる従業員のテーブルがあります。しかし、古いテーブルを保持し、時々プロシージャを実行して新しいテーブルを更新したいと思います。

これは私がこれまでに入手したコードであり、何時間ものエラーの後に最終的にコンパイルされますが、プロシージャを実行すると、「エントリが見つかりません」というメッセージが表示されます。

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で結果が見つからない場合は、例外を除いてそれをキャッチする必要があります(変数がnullであることをテストすることはできません)。

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 に答える