Ограничение целостности SQL-Родительский ключ не найден - PullRequest
0 голосов
/ 22 мая 2018

Я просматривал Интернет и их решения не решают мою проблему, поэтому я прошу помощи здесь, чтобы проверить, есть ли ошибки в моем кодировании.

Я хотел создать временную таблицу, заполненную другимиисходные таблицы, а затем внедрить его в таблицу фактов.Я проверил, совпадают ли тип данных и параметр или последовательность ключей, но все равно он выдает ошибку

"ORA-02291: ограничение целостности (SYSTEM.SYS_C007167) нарушено - родительский ключне найдено "

Таблица фактов:

CREATE TABLE DW_ITEMS7364 (
DW_ID int not null,
ManID char(5),
WHID char(5),
STKID char(5),
Profit number,
CONSTRAINT DW_ID PRIMARY KEY (DW_ID),
FOREIGN KEY(ManID) REFERENCES DW_MANUFACTURER7364,
FOREIGN KEY(WHID) REFERENCES DW_WAREHOUSE7364,
FOREIGN KEY(StkID) REFERENCES DW_STOCKITEM7364);


CREATE SEQUENCE seq_items7364 START WITH 101 increment by 1;

CREATE TRIGGER trg_items7364 BEFORE INSERT OR UPDATE ON DW_ITEMS7364
FOR EACH ROW
BEGIN
  SELECT seq_items7364.NEXTVAL
  INTO   :new.DW_ID
  FROM   dual;
END;

Временная таблица:

CREATE TABLE TEMP_TAB7364 AS( SELECT m.ManID, w.WHID, s.STKID, (s.SellingPrice-s.PurchasePrice) AS "Profit"
FROM MANUFACTURER7364 m LEFT OUTER JOIN STOCKITEM7364 s ON s.ManID = m.ManID
RIGHT OUTER JOIN WAREHOUSE7364 w on s.WHID = w.WHID WHERE s.SELLINGPRICE IS NOT NULL AND s.PURCHASEPRICE IS NOT NULL
);

Это мои исходные таблицы:

CREATE TABLE MANUFACTURER7364(
ManID char(5),
ManName varchar (25),
CityID char(5) NOT NULL,
PRIMARY KEY(ManID),
FOREIGN KEY(CityID) REFERENCES CITY7364);

CREATE TABLE WAREHOUSE7364(
WHID char(5),
MaxNoOfPallets number,
CostPerPallet number,
SecurityLevel char(1),
FreezerFacilities varchar(10),
QuarantineFacilities varchar(10),
CityID char(5) NOT NULL,
PRIMARY KEY(WHID),
FOREIGN KEY(CityID) REFERENCES CITY7364);

CREATE TABLE STOCKITEM7364(
StkID char(5),
StkName varchar(20),
SellingPrice number, 
PurchasePrice number,
ManID char(5) NOT NULL,
WHID char(5) NOT NULL,
PRIMARY KEY(StkID),
FOREIGN KEY(ManID) REFERENCES MANUFACTURER7364,
FOREIGN KEY(WHID) REFERENCES WAREHOUSE7364);

1 Ответ

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

Насколько я могу судить, ничего из того, что вы опубликовали, вызывает эту ошибку.

Дополнительным недостатком является способ выбора ограничений внешнего ключа.Если вы не называете его, Oracle назначит само имя, и оно будет выглядеть так, как вы его опубликовали: SYSTEM.SYS_C007167.

SQL> create table test
  2    (id_dept number,
  3     id_emp  number,
  4     foreign key (id_dept) references dept (deptno),
  5     foreign key (id_emp)  references emp  (empno));

Table created.

SQL> select constraint_name from user_constraints where table_name = 'TEST';

CONSTRAINT_NAME
------------------------------
SYS_C008172
SYS_C008173

SQL>

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

SQL> select column_name from user_cons_columns where constraint_name = 'SYS_C008173';

COLUMN_NAME
-----------------------    
ID_EMP

SQL>

Но, если вы назовете ограничение, оно будет намного проще:

SQL> create table test
  2    (id_dept number,
  3     id_emp  number,
  4     constraint fk_test_dept foreign key (id_dept) references dept (deptno),
  5     constraint fk_test_emp  foreign key (id_emp)  references emp  (empno));

Table created.

SQL> select constraint_name from user_constraints where table_name = 'TEST';

CONSTRAINT_NAME
------------------------------
FK_TEST_DEPT
FK_TEST_EMP

SQL>

Еще один главный недостаток, который замечает то, что написано перед точкой, здесь: SYSTEM.SYS_C007167.Да, это было бы SYSTEM.Короче, не делай этого.Оставьте SYS и SYSTEM в покое;они мощные, они особенные.Почему вы рискуете уничтожить базу данных, если вы (не) намеренно делаете что-то опасное?Создайте другого пользователя, предоставьте необходимые привилегии и работайте в этой схеме.

Если я правильно вас понял, когда вы создадите эту таблицу temp (TEMP_TAB7364), ее содержимое будет перенесено в DW_ITEMS7364 и - при этом - вы нажали ошибку.

Если это так, какова цель таблицы temp ?Вставьте прямо в целевую таблицу и сохраните ресурсы.Это потерпит неудачу?Конечно, будет, если вы не измените запрос.Как?Я не знаю - убедитесь, что вы не вставляете значения, которые не существуют ни в одной из трех таблиц, используемых для обеспечения ссылочной целостности.

Хотя, поскольку у вас уже есть temp Таблица, если она не слишком большая, можно найти (относительно) быстрый и грязный способ выяснить, какая строка ответственна за ошибку, с помощью цикла, такого как

begin
  for cur_r in (select col1, col2, ... from temp_table) loop
    begin
      insert into target (col1, col2, ...)
      values (cur_r.col1, cur_r.col2, ...);
    exception
      when others then 
        dbms_output.put_line(sqlerrm ||': '|| cur_r.col1 ||', '||cur_r.col2);
    end;
  end loop;
end;

Внутренний *Блок 1038 * здесь, чтобы убедиться, что код PL / SQL не выйдет при первой ошибке, но отобразит их все.Затем просмотрите эти значения и найдите причину, которая делает ваш запрос недействительным.

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