26

我有两张桌子,Table JOBTable USER是结构

 CREATE TABLE JOB
 (
   ID       NUMBER NOT NULL ,
   USERID   NUMBER,
   CONSTRAINT B_PK PRIMARY KEY ( ID ) ENABLE
 );

 CREATE TABLE USER
 (
   ID       NUMBER NOT NULL ,
   CONSTRAINT U_PK PRIMARY KEY ( ID ) ENABLE
 );

现在,我想添加外键约束来JOB引用USER表,如

Alter Table JOB ADD CONSTRAINT FK_USERID FOREIGN KEY(USERID) REFERENCES USER(ID);

这引发Oracle (ORA-02270) : no matching unique or primary key for this column-list error了一些调查,似乎我们需要有任何一个unique key or primary key约束,USERID但我不能有这个,因为一个人USERID可以有多个JOBS与他相关联,关于如何解决这个问题的任何想法或建议?

研究了 ORA-02270SO 相关问题

4

11 回答 11

45

ORA-2270 错误是一个简单的逻辑错误:当我们在外键中列出的列与父表上的主键或唯一约束不匹配时,就会发生这种错误。造成这种情况的常见原因是

  • 父级完全没有 PRIMARY KEY 或 UNIQUE 约束
  • 外键子句引用了父表中的错误列
  • 父表的约束是一个复合键,我们没有引用外键语句中的所有列。

您发布的代码中似乎都不是这种情况。但这是一条红鲱鱼,因为您的代码不会像您发布的那样运行。从之前的编辑来看,我认为您发布的不是实际代码,而是一些简化的示例。不幸的是,在简化过程中,您已经消除了导致 ORA-2270 错误的任何原因。

SQL> CREATE TABLE JOB
 (
   ID       NUMBER NOT NULL ,
   USERID   NUMBER,
   CONSTRAINT B_PK PRIMARY KEY ( ID ) ENABLE
 );  2    3    4    5    6  

Table created.

SQL> CREATE TABLE USER
 (
   ID       NUMBER NOT NULL ,
   CONSTRAINT U_PK PRIMARY KEY ( ID ) ENABLE
 );  2    3    4    5  
CREATE TABLE USER
             *
ERROR at line 1:
ORA-00903: invalid table name


SQL> 

该语句失败,因为 USER 是保留关键字,因此我们无法将表命名为 USER。让我们解决这个问题:

SQL> 1
  1* CREATE TABLE USER
SQL> a s
  1* CREATE TABLE USERs
SQL> l
  1  CREATE TABLE USERs
  2   (
  3     ID       NUMBER NOT NULL ,
  4     CONSTRAINT U_PK PRIMARY KEY ( ID ) ENABLE
  5*  )
SQL> r
  1  CREATE TABLE USERs
  2   (
  3     ID       NUMBER NOT NULL ,
  4     CONSTRAINT U_PK PRIMARY KEY ( ID ) ENABLE
  5*  )

Table created.

SQL> Alter Table JOB ADD CONSTRAINT FK_USERID FOREIGN KEY(USERID) REFERENCES USERS(ID);   

Table altered.

SQL> 

瞧!没有 ORA-2270 错误。

唉,我们在这里无法为您提供更多帮助。您的代码中有错误。你可以在这里发布你的代码,我们中的一个人可以发现你的错误。或者您可以检查自己的代码并自己发现它。


注意:早期版本的代码将 HOB.USERID 定义为 VARCHAR2(20)。因为 USER.ID 被定义为 NUMBER,所以尝试创建外键会抛出一个不同的错误:

ORA-02267: 列类型与引用的列类型不兼容

避免不匹配的一种简单方法是使用外键语法来默认列的数据类型:

CREATE TABLE USERs
 (
   ID    number NOT NULL ,
   CONSTRAINT U_PK PRIMARY KEY ( ID ) ENABLE
 );

CREATE TABLE JOB
 (
   ID       NUMBER NOT NULL ,
   USERID   constraint FK_USERID references users,
   CONSTRAINT B_PK PRIMARY KEY ( ID ) ENABLE
 );
于 2012-05-30T03:33:43.043 回答
8

Job 表中的数据类型 (Varchar2(20)) 与 USER 表中的数据类型不匹配 (NUMBER NOT NULL)。

于 2012-05-29T15:34:31.603 回答
6

在我的情况下,问题是由禁用的 PK 引起的。

为了启用它:

  1. 我寻找约束名称:

    SELECT * FROM USER_CONS_COLUMNS WHERE TABLE_NAME = 'referenced_table_name';

  2. 然后我取了约束名称,以便使用以下命令启用它:

    ALTER TABLE table_name ENABLE CONSTRAINT constraint_name;

于 2017-05-04T11:43:40.593 回答
2

我在我的场景中遇到了同样的问题,如下所示:

我首先创建了教科书表

create table textbook(txtbk_isbn varchar2(13)
primary key,txtbk_title varchar2(40),
txtbk_author varchar2(40) );

然后章节表:

create table chapter(txtbk_isbn varchar2(13),chapter_title varchar2(40), constraint pk_chapter primary key(txtbk_isbn,chapter_title), constraint chapter_txtbook foreign key (txtbk_isbn) references textbook (txtbk_isbn));

然后主题表:

create table topic(topic_id varchar2(20) primary key,topic_name varchar2(40));

现在,当我想在章节(具有复合主键)和主题(具有单列主键)之间创建一个名为 chapter_topic 的关系时,我遇到了以下查询的问题:

create table chapter_topic(txtbk_isbn varchar2(13),chapter_title varchar2(40),topic_id varchar2(20), primary key (txtbk_isbn, chapter_title, topic_id), foreign key (txtbk_isbn) references textbook(txtbk_isbn), foreign key (chapter_title) references chapter(chapter_title), foreign key (topic_id) references topic (topic_id));

解决方案是引用复合外键,如下所示:

create table chapter_topic(txtbk_isbn varchar2(13),chapter_title varchar2(40),topic_id varchar2(20), primary key (txtbk_isbn, chapter_title, topic_id), foreign key (txtbk_isbn, chapter_title) references chapter(txtbk_isbn, chapter_title), foreign key (topic_id) references topic (topic_id));

感谢 APC 的帖子,他在帖子中提到了以下声明:

造成这种情况的常见原因是
——父表完全没有约束
——父表的约束是一个复合键,我们没有引用外键语句中的所有列。
- 引用的 PK 约束存在但已禁用

于 2014-10-23T15:23:21.173 回答
2

很可能当您缺少未从父表定义的主键时。然后它发生。

就像在父级中添加主键定义如下:

ALTER TABLE "FE_PRODUCT" ADD CONSTRAINT "FE_PRODUCT_PK" PRIMARY KEY ("ID") ENABLE;

希望这会奏效。

于 2015-03-12T12:17:08.107 回答
2

方案是正确的,User.ID 必须是 User 的主键,Job.ID 应该是 Job 的主键,Job.UserID 应该是 User.ID 的外键。此外,您的命令似乎在语法上是正确的。

那么有什么问题呢?我相信您至少有一个 Job.UserID,它在 User.ID 中没有一对。例如,如果 User.ID 的所有值都是:1,2,3,4,6,7,8 并且 Job.UserID 的值是 5(不在 1,2,3,4,6 之间,7,8,这是 UserID 的可能值),您将无法创建外键约束。解决方案:

delete from Job where UserID in (select distinct User.ID from User);

将删除所有不存在用户的作业。您可能希望将这些迁移到包含存档数据的该表的副本。

于 2012-05-29T18:20:58.420 回答
2

我们有以下用于创建新表的脚本:

CREATE TABLE new_table
(
id                     NUMBER(32) PRIMARY KEY,
referenced_table_id    NUMBER(32)    NOT NULL,
CONSTRAINT fk_new_table_referenced_table_id
    FOREIGN KEY (referenced_table_id)
        REFERENCES referenced_table (id)
);

我们在执行时遇到了这个错误:

[42000][2270] ORA-02270: 此列列表没有匹配的唯一键或主键

在我们的案例中,问题是由于禁用了引用表的主键。我们通过以下方式启用了它

ALTER TABLE referenced_table ENABLE PRIMARY KEY USING INDEX;

之后我们使用第一个脚本创建了新表,没有任何问题

于 2020-02-18T15:05:58.180 回答
1

运行此命令时:

ALTER TABLE MYTABLENAME MODIFY CONSTRAINT MYCONSTRAINTNAME_FK ENABLE;

我收到了这个错误:

ORA-02270: no matching unique or primary key for this column-list
02270. 00000 -  "no matching unique or primary key for this column-list"
*Cause:    A REFERENCES clause in a CREATE/ALTER TABLE statement
          gives a column-list for which there is no matching unique or primary
          key constraint in the referenced table.
*Action:   Find the correct column names using the ALL_CONS_COLUMNS

引用的表具有匹配类型的主键约束。就我而言,这个错误的根本原因是主键约束被禁用。

于 2019-04-11T17:37:51.460 回答
0

你的 USERID 声明之间的区别不是问题吗

JOB: UserID is Varchar
USER: UserID is Number?
于 2012-05-29T15:36:50.990 回答
0

如果尚未在父表上定义主键,则可能会出现此问题。请尝试在现有表上定义主键。例如:

ALTER TABLE table_name
ADD PRIMARY KEY (the_column_which_is_primary_key);
于 2018-09-27T04:35:47.780 回答
-3
create table articles(code varchar2(30)constraint articles_pk primary key,titre varchar2(30),
support varchar2(30) constraint support_fk references supports(support),type_support varchar2(30),
numeroDePage varchar2(30),datepublication date,categorie varchar2(30)constraint categorie_fk references organismes(categorie),
tendance varchar2(30)constraint tendance_fk references apreciations(tendance));
于 2015-04-22T10:02:09.633 回答