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
之前插入protector
和master
值
还是出现同样的错误。
我认为这是因为您在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】:由于protector
和master
是主表,您应该首先在那里填充记录。然后,插入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)--不能插入值(可能是约束因素)的主要内容,如果未能解决你的问题,请参考以下文章