Sql (Oracle) - невозможно вставить значение (может быть фактором ограничения) - PullRequest
0 голосов
/ 15 мая 2018

Как видно из кода.Три таблицы имеют свой собственный первичный ключ.«protectmedalno» и «mastermedalno» являются внешним ключом игрового стола.Protemedmedalno не может быть нулевым.мастердеально может быть нулевым.Сначала я сбрасываю защитник таблицы, затем мастер, последний игрок, выпадающий из игры.

Существует слабая связь между игроком стола и мастером стола.
Нет проблем с вставкой значения защитника и мастера.Но вставив значение в проигрыватель таблицы, это произойдет: * Причина: значение внешнего ключа не соответствует значению первичного ключа.* Действие: удалите внешний ключ или добавьте соответствующий первичный ключ.

Я думаю, что это проблема с ограничением.

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 );

Ответы [ 6 ]

0 голосов
/ 15 мая 2018

Заполнение «родительских» таблиц первым (как предложили наши коллеги) - это шаг к решению проблемы. Для того чтобы ограничение внешнего ключа работало правильно, я предлагаю также изменить код 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 

Пока все хорошо. При ВСТАВКЕ в ИГРОКА мы получаем:

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

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

Предложение: используйте тот же тип данных для внешнего ключа и ссылочного ключа. Просто удалите таблицу 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 );

Теперь выполните ВСТАВКИ.

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
0 голосов
/ 15 мая 2018

Чтобы вставить данные в таблицу игрока, вам нужна запись в таблице защиты. Это из-за ограничения внешнего ключа. При вставке данных в таблицу с внешним ключом (который в данном случае Protector vs Player не может быть нулевым), сначала необходимо создать внешнюю запись.

 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;

Надеюсь, это поможет, счастливой отладки:)

0 голосов
/ 15 мая 2018

Сначала необходимо вставить защитник и мастер, затем вставить проигрыватель, поскольку игрок ссылается на мастер и защитник, и значения должны быть внутри.

В противном случае округлить при удалении ...

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');

Если вы сначала удалите удаление с плеера, а затем с защитника и мастера.

0 голосов
/ 15 мая 2018

Всегда включает столбцы при выполнении insert. Вы также должны использовать одинарные кавычки только для строковых констант и констант даты.

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

Я не думаю, что проблема именно на player, но вы должны сделать это для всех ваших inserts, и вы найдете проблему.

0 голосов
/ 15 мая 2018

Поскольку 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, которая на самом делесуществует.

0 голосов
/ 15 мая 2018

Вы вставляете в неправильном порядке: сначала вы должны вставить мастер и защитник, чтобы при вставке проигрывателя он мог ссылаться на них:

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...