Oracle - 插入存储过程外键

时间:2014-12-05 04:02:15

标签: sql database oracle

说明:

创建两个名为 员工 部门 的表。在表名前加上您的姓名缩写。通过名为 dept 的列链接两个表(外键)。为每个表格组成几个列名称。

员工表:

create table bsemployees(
dept        number primary key,
empName     varchar2(20),
salary      number
);

部门表:

create table bsdepartments(
dept        number references bsemployees(dept),
deptName    varchar2(20)
);

编写以下存储过程:

•在 员工 表格中插入一行。如果部门不存在。将其插入 部门 表格。

create or replace procedure sp_employees(
    a_dept IN number, 
    a_empName IN varchar2, 
    a_salary IN number
)
as
    vCount  number;
BEGIN   
    sp_check_dept(a_dept,vCount);

    insert into bsemployees values(a_dept, a_empName, a_salary);

    if vCount = 0 then
        dbms_output.put_line('**DEPT DOES NOT EXIST**');
        insert into bsdepartments (dept, deptName) values(a_dept, NULL);
    end if;
END;
/

create or replace procedure sp_check_dept(
    a_dept IN number,
    vCount OUT number
)
as
BEGIN
    select count(*)
    into vCount
    from bsdepartments
    where dept = a_dept;
end;
/

•在departments表中插入一行。

create or replace procedure sp_departments(
    a_dept IN number, 
    a_deptName IN varchar2
)
as
BEGIN
    insert into bsdepartments values(a_dept, a_deptName);
END;
/

除了我尝试在 部门 表中插入一行时,我得到了完整的信息约束 - 未找到父键错误。

如果我execute sp_employees(5, 'John Doe', 90000);它会显示***DEPT DOES NOT EXIST***并继续将数据插入 bsemployees 并将部门#插入< strong> bsdepartments ,deptName将根据我的if-then语句留空。做一个选择(*)告诉我这个。

但是,如果我继续execute sp_departments(1, 'human resources');将行放入 部门 ,我会收到父键错误。我知道我正在尝试插入没有父键的东西,但我不知道如何修复它。

2 个答案:

答案 0 :(得分:1)

你对表department的反应很糟糕。它应该如下链接

create table bsdepartments(
dept        number primary key,
deptName    varchar2(20)
);

,它应该链接到员工表

create table bsemployees(
dept        number references bsdepartments(dept),
empName     varchar2(20),
salary      number
);

然后,如果您尝试插入execute sp_departments(1, 'human resources');,它将会执行 那么你必须插入员工。

此处员工与部门相关,而不是部门与员工相关。

答案 1 :(得分:1)

您的表格设计不太正确 - 需要将dept主键作为外键添加到员工(而不是主键),并且员工应该拥有自己的主键:

create table bsdepartments(
  dept        number primary key,
  deptName    varchar2(20)
);


create table bsemployees(
  empName     varchar2(20) primary key,
  dept        number references bsdepartments(dept),
  salary      number
);

然后你可以在check_dept过程中执行'add if not exists'逻辑:

create or replace procedure sp_check_dept(
    a_dept IN number
)
as
   vCount number
BEGIN
    select count(*)
        into vCount
        from bsdepartments
        where dept = a_dept;

    if (vCount = 0) then
        dbms_output.put_line('**DEPT DOES NOT EXIST**');
        insert into bsdepartments (dept, deptName) values(a_dept, NULL);
    end if;
end;

然后简化了员工插入过程,因为它应该由部门保证:

create or replace procedure sp_insertEmployee(
    a_dept IN number, 
    a_empName IN varchar2, 
    a_salary IN number
)
as
BEGIN   
    sp_check_dept(a_dept);

    insert into bsemployees values(a_dept, a_empName, a_salary);
END

注释

  • 建议您将过滤器命名为与其目的一致,例如: insertEmployee vs仅employees
  • 正如您所指出的,“添加即使不存在”方法的问题是您没有足够的数据来完全填充department表,因此空列(但这就是您的讲师)要求)