【问题标题】:Oracle - Insert Stored Procedure Foreign KeyOracle - 插入存储过程外键
【发布时间】:2014-12-05 04:02:14
【问题描述】:

说明:

创建两个表,分别命名为 employeesdepartments。在表格名称前加上您的姓名首字母。通过名为 dept 的列链接两个表(外键)。为每个表组成几个列名。

员工表:

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

部门表:

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

编写以下存储过程:

• 在employees 表中插入一行。如果部门不存在。将其插入到 departments 表中。

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;
/

• 在部门表中插入一行。

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;
/

除了当我尝试在 departments 表中插入一行时,我得到了完整性约束 - 找不到父键错误。

如果我执行execute sp_employees(5, 'John Doe', 90000);,它将显示***DEPT DOES NOT EXIST***,并将继续将数据插入bsemployees,并将部门#插入bsdepartments 和 deptName 将根据我的 if-then 语句留空。执行 select(*) 会显示这一点。

但是,如果我继续执行 execute sp_departments(1, 'human resources'); 将一行放入 departments,我会收到父键错误。我了解我正在尝试插入一些没有父键但我不知道如何修复它的内容。

【问题讨论】:

    标签: sql database oracle


    【解决方案1】:

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

    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 proc 中执行“如果不存在则添加”逻辑:

    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
    

    注意事项

    • 建议您根据其用途命名 proc,例如insertEmployeeemployees
    • 正如您所指出的,“如果不存在则添加”方法的问题是您没有足够的数据来完全填充 department 表,因此为空列(但这是您的讲师要求的)

    【讨论】:

      【解决方案2】:

      您对表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');,它将执行 然后你必须插入员工。

      这里员工与部门相关,而不是部门与员工相关。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-08-27
        • 1970-01-01
        • 1970-01-01
        • 2021-10-12
        • 2017-03-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多