外键语句中的主键歧义

时间:2014-11-12 04:13:28

标签: sql oracle oracle11g constraints

Oracle是否自动确定约束语句中的主键?

CREATE TABLE [BANK] (
   [bank_id] SMALLINT NOT NULL,
   PRIMARY KEY (bank_id)
);

CREATE TABLE [ACCOUNT] (
   [account_id] SMALLINT NOT NULL
   PRIMARY KEY (account_id)
);


CONSTRAINT fk_bank_id FOREIGN KEY (bank_id)
   REFERENCES BANK /* put this in account create table statement */

当我没有明确说明主键而只是使用表名时,它会自动确定BANK表的主键吗?

(抽象)的命名约定:

PRIMARY KEY (primary_key) 

影响约束条款,若然,以何种方式?

2 个答案:

答案 0 :(得分:3)

documentation for the references clause将引用的列名称显示为可选。所以我们可以创建一个只指定引用表的外键....

SQL> create table t23 (
  2  id number not null
  3  , col_1 varchar2(10) not null
  4  , constraint t23_pk primary key (id)
  5  )
  6  /

Table created.

SQL> create table t42 (
  2  id number not null
  3  , fk_id number not null
  4  , col_a varchar2(10)
  5  , col_b varchar2(10)
  6  , constraint t23_pk primary key (id)
  7  , constraint t42_t23_fk foreign key (fk_id) references t23
  8  )
  9  /

Table created.

SQL> 

易腻的柠檬挤压。让我们通过向父表添加唯一键来增加赌注....

SQL> drop table t23 cascade constraints;

Table dropped.

SQL> drop table t42 cascade constraints;

Table dropped.

SQL> create table t23 (
  2  id number not null
  3  , col_1 varchar2(10) not null
  4  , constraint t23_pk primary key (id)
  5  , constraint t23_uk unique (col_1)
  6  )
  7  /
Table created.

SQL> create table t42 (
  2  id number not null
  3  , fk_id number not null
  4  , col_a varchar2(10)
  5  , col_b varchar2(10)
  6  , constraint t42_pk primary key (id)
  7  , constraint t42_t23_fk foreign key (fk_id) references t23 
  8  )
  9  /

Table created.

SQL> 

Oracle仍然计算出主键。但是假设我们想要引用那个唯一的密钥呢?

SQL> drop table t42 cascade constraints;

Table dropped.

SQL> create table t42 (
  2  id number not null
  3  , fk_id number not null
  4  , col_a varchar2(10)
  5  , col_b varchar2(10)
  6  , constraint t42_pk primary key (id)
  7  , constraint t42_t23_fk foreign key (col_a) references t23 
  8  )
  9  /

     , constraint t42_t23_fk foreign key (col_a) references t23
                                         *
ERROR at line 7:
ORA-02267: column type incompatible with referenced column type


SQL> create table t42 (
  2  id number not null
  3  , fk_id number not null
  4  , col_a varchar2(10)
  5  , col_b varchar2(10)
  6  , constraint t42_pk primary key (id)
  7  , constraint t42_t23_fk foreign key (col_a) references t23 (col_1)
  8  )
  9  /

Table created.

SQL> 

所以我们可以看到,as the documentation says,Oracle默认引用的密钥是主键。当我们想要引用另一个键时,我们必须识别引用表中的约束列。

  

“(抽象)的命名约定:”

不确定你从哪里获得“约定”。它不受语法支持,因此其效果是抛出异常,ORA-00904: "PRIMARY_KEY": invalid identifier(如果没有下划线,则尝试ORA-00907)。这是有道理的,因为主键是引用的默认值,并且它不能用于引用唯一键,因为表可以有多个键。

答案 1 :(得分:0)

'不确定这是你在寻找什么。但引用the documentation

  

外键约束
  [...]
   如果仅标识父表或视图并省略列名,则外键会自动引用父表或视图的主键。外键和引用键的相应列或列必须按顺序和数据类型匹配。