Почему эта ошибка появляется у меня на sql developer - PullRequest
0 голосов
/ 10 ноября 2018

создаю таблицу "Funcionario" но потом таблицы "Виагем" и "Энкоменда" покажи мне эту ошибку. Я не поняла почему, кто-нибудь может мне помочь? Я могу поделиться всем сценарием, если вы хотите увидеть все. Появляющаяся ошибка:

"ORA-02270: нет соответствующего уникального или первичного ключа для этого списка столбцов.

Предложение REFERENCES в операторе CREATE / ALTER TABLE дает столбец-список, для которого нет соответствующего уникального или первичного ключа ограничение в ссылочной таблице.

[РЕДАКТИРОВАТЬ] SCRIPT

-- Criar Tabela Zona Geografica

CREATE TABLE ZonaGeografica(
id_zona_geo INTEGER CONSTRAINT pk_ZonaGeografica_id_zona_geo PRIMARY KEY,
latitude INTEGER NOT NULL,
longitude INTEGER NOT NULL
);

-- Criar Tabela Armazem

CREATE TABLE Armazem(
cod_armazem INTEGER CONSTRAINT pk_Armazem_cod_armazem PRIMARY KEY,
id_zona_geo INTEGER NOT NULL,
nome VARCHAR(40) NOT NULL,
morada VARCHAR(50) NOT NULL,
CONSTRAINT fk_ZonaGeografica_id_zona_geo FOREIGN KEY (id_zona_geo) REFERENCES ZonaGeografica(id_zona_geo)
);

-- Criar Tabela TipoVeiculo

CREATE TABLE TipoVeiculo(
tipo_veiculo VARCHAR(20) CONSTRAINT pk_TipoVeiculo_tipo_veiculo PRIMARY KEY,
capacidade_volume INTEGER NOT NULL,
capacidade_peso INTEGER NOT NULL
);

-- Criar Tabela Veiculo

CREATE TABLE Veiculo(
cod_veiculo INTEGER NOT NULL,
tipo_veiculo VARCHAR(20) NOT NULL,
matricula VARCHAR(8) NOT NULL,
marca VARCHAR(20) NOT NULL,
modelo VARCHAR(5) NOT NULL,
nr_apolice INTEGER NOT NULL,
nr_quilometros INTEGER NOT NULL,
CONSTRAINT pk_Veiculo_cod_veiculo_tipo_veiculo PRIMARY KEY(cod_veiculo, tipo_veiculo),
CONSTRAINT fk_Veiculo_tipo_veiculo FOREIGN KEY (tipo_veiculo) REFERENCES TipoVeiculo(tipo_veiculo),
CONSTRAINT ck_Veiculo_matricula CHECK(REGEXP_LIKE(matricula ,'[0-9]{2}-[A-Z]{2}-[0-9]{2}|[0-9]{2}-[0-9]{2}-[A-Z]{2}|[A-Z]{2}-[0-9]{2}-[0-9]{2}'))
);

-- Criar Tabela Funcionario

CREATE TABLE Funcionario(
id_func INTEGER CONSTRAINT pk_Funcionario_id_func PRIMARY KEY,
id_tipo INTEGER NOT NULL,
cod_armazem INTEGER NOT NULL,
cod_supervisor INTEGER NOT NULL,
cc INTEGER NOT NULL CONSTRAINT ck_Funcionario_cc CHECK(REGEXP_LIKE(cc ,'[0-9]{8}-[0-9]{1}-[A-Z]{2}[0-9]{1}')),
nome_func VARCHAR(40) NOT NULL,
morada_func VARCHAR(40) NOT NULL,
nif_func INTEGER NOT NULL UNIQUE CONSTRAINT ck_Funcionario_nif_func CHECK(REGEXP_LIKE(nif_func ,'[0-9]{7}')),
salario_mensal NUMERIC(*,2) NOT NULL,
CONSTRAINT fk_Funcionario_id_tipo FOREIGN KEY (id_tipo) REFERENCES Categoria(id_tipo),
CONSTRAINT fk_Funcionario_cod_armazem FOREIGN KEY (cod_armazem) REFERENCES Armazem(cod_armazem),
CONSTRAINT fk_Funcionario_cod_supervisor FOREIGN KEY (cod_supervisor) REFERENCES Funcionario(id_func)
);

-- Criar Tabela Categoria

CREATE TABLE Categoria(
id_tipo INTEGER CONSTRAINT pk_Categoria_id_tipo PRIMARY KEY,
tipo VARCHAR(20) NOT NULL
);

-- Criar Tabela Viagem


CREATE TABLE Viagem(
nr_viagem INTEGER CONSTRAINT pk_Viagem_nr_viagem PRIMARY KEY,
id_tipo INTEGER NOT NULL,
id_func INTEGER NOT NULL,
cod_veiculo INTEGER NOT NULL,
tipo_veiculo VARCHAR(20) NOT NULL,
data_partida DATE NOT NULL,

CONSTRAINT fk_Viagem_id_tipo FOREIGN KEY (id_tipo) REFERENCES Categoria(id_tipo),
CONSTRAINT fk_Viagem_id_func FOREIGN KEY (id_func) REFERENCES Funcionario(id_func),
CONSTRAINT fk_Viagem_cod_veiculo FOREIGN KEY (cod_veiculo) REFERENCES Veiculo(cod_veiculo),
CONSTRAINT fk_Viagem_tipo_veiculo FOREIGN KEY (tipo_veiculo) REFERENCES TipoVeiculo(tipo_veiculo)
);


-- Criar Tabela Encomenda

CREATE TABLE Encomenda(
id_encomenda INTEGER CONSTRAINT pk_Encomenda_id_encomenda PRIMARY KEY,
cod_armazem INTEGER NOT NULL,
cod_veiculo INTEGER NOT NULL,
nr_viagem INTEGER NOT NULL,
CONSTRAINT fk_Encomenda_nr_viagem FOREIGN KEY (nr_viagem) REFERENCES Viagem(nr_viagem),
id_func INTEGER NOT NULL,
CONSTRAINT fk_Encomenda_cod_armazem FOREIGN KEY (cod_armazem) REFERENCES Armazem(cod_armazem),
CONSTRAINT fk_Encomenda_cod_veiculo FOREIGN KEY (cod_veiculo) REFERENCES Veiculo(cod_veiculo),
CONSTRAINT fk_Encomenda_id_func FOREIGN KEY (id_func) REFERENCES Funcionario(id_func)
);

Ответы [ 2 ]

0 голосов
/ 10 ноября 2018

Сообщение об ошибке довольно ясно (или, по крайней мере, лучше, чем некоторые); у вас есть внешний ключ, который пытается ссылаться на столбцы, которые не образуют уникальный или первичный ключ в родительской таблице.

В Viagem у вас есть:

CONSTRAINT fk_Viagem_cod_veiculo FOREIGN KEY (cod_veiculo) REFERENCES Veiculo(cod_veiculo),

но первичный ключ в Veiculo представляет собой комбинацию из двух столбцов:

CONSTRAINT pk_Veiculo_cod_veiculo_tipo_veiculo PRIMARY KEY(cod_veiculo, tipo_veiculo),

Вы не можете ссылаться на один столбец из этого ключа, так как этот отдельный столбец сам по себе не будет уникальным, что приведет к неоднозначности. Таким образом, очевидное (но, вероятно, неправильное) исправление заключается в изменении Viagem для ссылки на оба столбца:

CONSTRAINT fk_Viagem_cod_veiculo FOREIGN KEY (cod_veiculo, tipo_veiculo)
  REFERENCES Veiculo(cod_veiculo, tipo_veiculo),

(Если бы вы это сделали, тогда действительно не требовалось бы также ограничение fk_Viagem_tipo_veiculo, поскольку tipo_veiculo является частью FK до Veiculo, и эта таблица уже имеет свой собственный FK до TipoVeiculo. )

Но у вашей таблицы Encomenda такая же проблема; у вас есть:

CONSTRAINT fk_Encomenda_cod_veiculo FOREIGN KEY (cod_veiculo) REFERENCES Veiculo(cod_veiculo),

там тоже. Но для этой таблицы у вас нет столбца id_tipo, поэтому вы не можете включить это в FK.

Что указывает на более вероятное решение с помощью вопроса - почему Veiculo вообще включает tipo_veiculo в свой PK? Похоже, что cod_veiculo должен быть уникальным сам по себе; в этом случае измените этот PK на просто:

CONSTRAINT pk_Veiculo_cod_veiculo_tipo_veiculo PRIMARY KEY(cod_veiculo),

и оставьте оба Viagem и Encomenda такими, как они у вас уже есть, причем все их Fk ссылаются на один столбец каждый. (Хотя вы можете решить, нужен ли вообще Viagem столбец id_tipo, поскольку вы можете получить его из Veiculo через связанный cod_veiculo ...)

Если вы действительно хотите сохранить этот PK как есть, то вам нужно будет добавить отдельный уникальный ключ только для cod_veiculo, который бы тогда удовлетворял fk_Encomenda_cod_veiculo - но это выглядит неправильно.

0 голосов
/ 10 ноября 2018

Вот что не так

CONSTRAINT fk_Viagem_cod_veiculo FOREIGN KEY (cod_veiculo) REFERENCES Veiculo(cod_veiculo)

Для таблицы Viagem у вас есть это FOREIGN KEY, которое относится только к части составного PRIMARY KEY в Veiculo (cod_veiculo, tipo_veiculo)

то же самое с Encomenda

CONSTRAINT fk_Encomenda_cod_veiculo FOREIGN KEY(cod_veiculo) REFERENCES Veiculo(cod_veiculo)

Исправьте ваш дизайн так, чтобы комбинация FOREIGN KEY соответствовала с UNIQUE KEY/PRIMARY KEY в ссылочных таблицах.

...