Sql (Oracle)--不能插入值(可能是约束因素)

Posted

技术标签:

【中文标题】Sql (Oracle)--不能插入值(可能是约束因素)【英文标题】:Sql (Oracle)-- cannot insert value(could be the constraint factor) 【发布时间】:2018-10-25 08:07:14 【问题描述】:

正如您在代码中看到的那样。三张表都有自己的主键。 “protectmedalno”和“mastermedalno”是玩家表的外键。 protectedmedalno 不能为空。 masterdealno 可以为空。我先drop table protector,然后drop master,最后一个drop player。

赌桌玩家和赌桌主人之间的关系较弱。 插入protector和master的值是没有问题的。 但是将值插入到桌面播放器中,它会发生: *原因:外键值没有匹配的主键值。 *操作:删除外键或添加匹配的主键。

我认为是约束的问题。

insert into player values('01','Joe','101','');
insert into player values('02','Elsa','102','201');

insert into protector values('101','Dragon');
insert into protector values('102','Lion');
insert into master values('201','Fairy')
commits;

它可以显示保护表和主表。 但它无法显示玩家表。

drop table protector;
drop table master;
drop table player;

CREATE TABLE player (
    playno           NUMBER(2) NOT NULL,
    playname         VARCHAR2(30) NOT NULL,
    protectmedalno   CHAR(10) NOT NULL,
    mastermedalno    CHAR(10)
);


ALTER TABLE player ADD CONSTRAINT play_pk PRIMARY KEY ( playno );

CREATE TABLE protector (
    protectmedalno   CHAR(3) NOT NULL,
    protectname      VARCHAR2(30) NOT NULL   
);


ALTER TABLE protector ADD CONSTRAINT protector_pk PRIMARY KEY ( protectmedalno );

CREATE TABLE master (
    mastermedalno   CHAR(3) NOT NULL,
    mastername      VARCHAR2(30) NOT NULL   
);

ALTER TABLE master ADD CONSTRAINT master_pk PRIMARY KEY ( mastermedalno );


ALTER TABLE player
    ADD CONSTRAINT player_protector_fk FOREIGN KEY ( protectmedalno )
        REFERENCES protector ( protectmedalno );

ALTER TABLE player
    ADD CONSTRAINT player_master_fk FOREIGN KEY ( mastermedalno )
        REFERENCES master ( mastermedalno );

【问题讨论】:

尝试在player 之前插入protectormaster 还是出现同样的错误。 我认为这是因为您在player 表中的mastermedalno 列中插入'' 并且它与任何内容都不匹配,请尝试在那里写null 【参考方案1】:

您插入的顺序错误:您必须先插入主设备和保护设备,以便在插入播放器时它可以引用它们:

insert into protector values('101','Dragon');
insert into protector values('102','Lion');
insert into master values('201','Fairy');

insert into player values('01','Joe','101',NULL);
insert into player values('02','Elsa','102','201');

编辑:'' 不是 NULL,它是一个空字符串。要插入 null,请使用显式 NULL 关键字。

【讨论】:

【参考方案2】:

由于protectormaster 是主表,您应该首先在那里填充记录。然后,插入player 并引用这些记录:

insert into protector values('101','Dragon');
insert into protector values('102','Lion');
insert into master values('201','Fairy');

insert into player values('01','Joe','101','201');   -- refer to master
insert into player values('02','Elsa','102','201');  -- refer to master

请注意,我将插入编辑到 player 表中,以便两条记录都引用 master 表中实际存在的记录。

【讨论】:

乔没有大师。我试着像你说的那样插入订单,条件一样。我应该清理桌子吗?或者如何清理它? 如果可以,只需删除所有内容,再次创建表,然后使用正确的插入顺序。不确定Oracle是否允许NULL外键,但我认为缺少的外键应该是NULL,而不是空字符串。 我在开始时也尝试了 null 而不使用建议的顺序。 null 似乎无法使用。 @YeiBi Oracle中的外键can be NULL,所以肯定还有问题。【参考方案3】:

总是在执行insert 时包含列。您还应该只对字符串和日期常量使用单引号。

insert into player(playno, playname, protectmedalno, mastermedalno) 
     values(1, 'Joe', '101', '');

我不认为问题出在player,但您应该为所有inserts 执行此操作,您会发现问题。

【讨论】:

【参考方案4】:

您首先必须插入保护器和主控器,然后插入播放器,因为播放器指的是主控器和保护器,并且值必须在里面。

否则对删除进行舍入...

insert into protector values('101','Dragon');
insert into protector values('102','Lion');

insert into master values('201','Fairy');

insert into player values('01','Joe','101','');
insert into player values('02','Elsa','102','201');

如果你先从播放器中删除,然后从保护者和主人中删除。

【讨论】:

【参考方案5】:

要在播放器表中插入数据,您需要保护器表中的记录。这是因为外键限制。 在具有外键的表中插入数据时(在这种情况下,保护者与播放器不能为空),您必须先创建外记录。

 1. insert into protector values('101','Dragon');
    2. insert into player values('01','Joe','101','');
    3. insert into protector values('102','Lion');
    4. insert into master values('201','Fairy');
    5. insert into player values('02','Elsa','102','201');
    commits;

希望对你有帮助,调试愉快:)

【讨论】:

【参考方案6】:

首先填充“父”表(正如我们的同事所建议的)是解决问题的一步。为了让外键约束能够正常工作,我也建议修改 DDL 代码。

有了您的表(使用 Oracle 12c),我们可以执行以下操作:

begin  
  insert into master ( mastermedalno, mastername ) values ('201','Fairy') ;

  insert into protector ( protectmedalno, protectname ) 
    values( '101', 'Dragon');
  insert into protector ( protectmedalno, protectname ) 
    values( '102', 'Lion');
end ;
/

SQL> select * from master;

MAS MASTERNAME                    
--- ------------------------------
201 Fairy                         

SQL> select * from protector ;

PRO PROTECTNAME                   
--- ------------------------------
101 Dragon                        
102 Lion 

到目前为止一切顺利。当插入到 PLAYER 中时,我们得到:

insert into player ( playno, playname, protectmedalno, mastermedalno )
  values('02', 'Elsa', '102', '201');

-- ORA-02291: integrity constraint (...PLAYER_MASTER_FK) violated - parent key not found

建议:对外键和被引用键使用 same 数据类型。只需删除 PLAYER 表(包括其约束),然后重新创建它:

drop table player cascade constraints ;

CREATE TABLE player (
    playno           NUMBER(2) NOT NULL,
    playname         VARCHAR2(30) NOT NULL,
    protectmedalno   CHAR(3) NOT NULL,     -- changed (was: CHAR(10))
    mastermedalno    CHAR(3)               -- changed (was: CHAR(10))
);

ALTER TABLE player
    ADD CONSTRAINT player_protector_fk FOREIGN KEY ( protectmedalno )
        REFERENCES protector ( protectmedalno );

ALTER TABLE player
    ADD CONSTRAINT player_master_fk FOREIGN KEY ( mastermedalno )
        REFERENCES master ( mastermedalno );

现在执行 INSERT。

begin
  insert into player values('01','Joe','101','');     -- original INSERT
  insert into player values('02','Elsa','102','201'); -- original INSERT
  commit;
end;
/
-- PL/SQL procedure successfully completed.

这些表现在包含以下数据:

SQL> select * from player ;
PLAYNO  PLAYNAME  PROTECTMEDALNO  MASTERMEDALNO  
1       Joe       101             NULL           
2       Elsa      102             201            

SQL> select * from master ;
MASTERMEDALNO  MASTERNAME  
201            Fairy       

SQL> select * from protector;
PROTECTMEDALNO  PROTECTNAME  
101             Dragon       
102             Lion  

两个外键约束现在都有效吗?是的。

SQL> insert into player values('03','Fifi','101','202');
Error starting at line : 1 in command -
insert into player values('03','Fifi','101','202')
Error report -
ORA-02291: integrity constraint (...PLAYER_MASTER_FK) violated - parent key not found

SQL> insert into player values('03','Fifi','103','201');
Error starting at line : 1 in command -
insert into player values('03','Fifi','103','201')
Error report -
ORA-02291: integrity constraint (...PLAYER_PROTECTOR_FK) violated - parent key not found

【讨论】:

以上是关于Sql (Oracle)--不能插入值(可能是约束因素)的主要内容,如果未能解决你的问题,请参考以下文章

SQLSERVER 如何添加0或1的约束,默认是0

SQL插入的唯一约束-ORACLE

SQL 如何把现有字段设为not null

SQL DEFAULT 约束

SQL DEFAULT 约束

Oracle 存储过程插入非重复值和外键约束的考虑