为什么在SQL Developer上出现此错误

时间:2018-11-10 16:14:35

标签: sql oracle create-table

我创建表“ Funcionario” 但是表格“ Viagem”和“ Encomenda” 告诉我这个错误。我不明白为什么,有人可以帮助我吗?如果您想全部查看,我可以共享所有脚本。 出现的错误是:

  

“ ORA-02270:此列列表没有匹配的唯一键或主键。

     

CREATE / ALTER TABLE语句中的REFERENCES子句提供了一个   没有匹配的唯一键或主键的列列表   约束在引用表中。

[编辑]脚本

-- 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 :(得分:2)

这是怎么了

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匹配。

答案 1 :(得分:0)

该错误消息非常清楚(或者至少比某些错误更好);您有一个外键试图引用在父表中不构成唯一键或主键的列。

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_veiculoVeiculo的FK的一部分,并且该表已经有自己的FK到TipoVeiculo。)

但是您的Encomenda表存在相同的问题;你有:

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

也有。但是对于该表,您没有id_tipo列,因此您不能将其包括在FK中。

通过一个问题,哪个指出了更可能的解决方案-为什么Veiculo的PK中完全包含tipo_veiculocod_veiculo 应该应该看起来是唯一的;在这种情况下,请将PK更改为:

CONSTRAINT pk_Veiculo_cod_veiculo_tipo_veiculo PRIMARY KEY(cod_veiculo),

,将ViagemEncomenda保留为原来的样子,它们的Fk都引用一列。 (尽管您可能要考虑Viagem是否实际上确实需要id_tipo列,因为yuo可以通过链接的Veiculocod_veiculo中获取它))

如果您真的想保留该PK,则仅需为cod_veiculo添加一个单独的唯一密钥,这样就可以满足fk_Encomenda_cod_veiculo-但这是错误的。