如何从多个列引用外键(不一致的值)

时间:2016-09-18 15:42:39

标签: sql oracle foreign-keys

我有三张桌子:

第一个是emps:

create table emps (id number primary key , name nvarchar2(20));

第二个是汽车:

create table cars (id number primary key , car_name varchar2(20));

第三个是帐户:

create table accounts (acc_id number primary key, woner_table nvarchar2(20) , 
                   woner_id number references emps(id) references cars(id));

现在我为选定的表提供了这些值:

EMPS:

ID         Name
-------------------
1          Ali
2          Ahmed

汽车:

ID           Name
------------------------
107          Camery 2016
108          Ford 2012

我想帐户表中插入值,使其数据应如下所示:

帐户:

Acc_no         Woner_Table     Woner_ID
------------------------------------------
11013          EMPS           1
12010          CARS           107

我尝试执行此SQL语句:

Insert into accounts (acc_id , woner_table , woner_id) values (11013,'EMPS',1);

但是我收到此错误:

ERROR at line 1:
ORA-02291: integrity constraint (HR.SYS_C0016548) violated - parent key not found.

发生此错误是因为cars表中不存在woner_id列的值。

我的工作需要这样的链接表。

我该如何解决这个问题?!..

意思是:如何以前一种方式引用表格并插入值而没有此问题?...

3 个答案:

答案 0 :(得分:2)

SQL中的一个关系很棘手。您的数据结构是一种可能性:

 <script>
      $(document).ready(function(){
                setInterval(function() {
                   $.get('check_session.php', function(data) {
                    alert('Load was performed.');
                    console.log('data: '+data)
                });
            }, 5000);
       });
</script>

您可以在选择中获取create table accounts ( acc_id number primary key, emp_id number references emps(id), car_id number references car(id), id as (coalesce(emp_id, car_id)), woner_table as (case when emp_id is not null then 'Emps' when car_id is not null then 'Cars' end), constraint chk_accounts_car_emp check (emp_id is null or car_id is null) ); 。但是,对于插入,您需要明确:

id

注意:早期版本的Oracle不支持虚拟列,但您可以使用视图执行几乎相同的操作。

答案 1 :(得分:1)

您的方法应该更改,以便您的帐户表包含两个外键字段 - 每个外表一个。像这样:

create table accounts (acc_id number primary key,
                       empsId number references emps(id),
                       carsId number references cars(id));

答案 2 :(得分:1)

最简单,最直接的方法是STLDeveloper说,添加额外的FK列,每个表一个。这也带来了数据库能够强制执行参照完整性的好处。

但是,如果您选择不这样做,则下一个选项是使用一个FK列作为FK值,使用第二列指示值所指的表。这使得列数小=最大2,无论具有FK的表的数量。但是,这显着增加了应用程序逻辑和/或PL / SQL,SQL的编程负担。当然,你完全失去了RI的数据库执行。