【问题标题】:Primary key ambiguities in foreign key statements外键语句中的主键歧义
【发布时间】:2014-11-12 04:13:28
【问题描述】:

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) 

影响约束子句,如果是,以什么方式影响?

【问题讨论】:

    标签: sql oracle oracle11g constraints


    【解决方案1】:

    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> 
    

    简单的 peasy 柠檬榨汁。让我们通过向父表添加唯一键来增加赌注......

    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,如果你尝试不使用下划线)。这是有道理的,因为主键是引用的默认值,它不能用于引用唯一键,因为表可以有多个。

    【讨论】:

      【解决方案2】:

      '不确定这是您要查找的内容。但要引用the documentation

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多