Pergunta

Eu tenho 2 mesas

T_Foo
foo_id
fooHeader

T_FooBodys
foo_id
foobody

Foo_id são a chave primária para as duas tabelas. Na segunda tabela, Foo_id é a chave estrangeira da primeira tabela. Eu gero o PK para ambos os valores de tabela usando uma sequência e tento transformar a inserção - uma vez no fooheader e duas vezes em Foobody.

Meu código trava na segunda inserção no T_FOOBODYS no loop do erro "ORA-00001: restrição exclusiva (userID.foobodys_pk) violada"

Então, eu tenho 2 perguntas:

1) Qual é a diferença fundamental entre o MSSQL Server e o Oracle aqui? Isso funcionou bem no SQL Server! Eu tinha um relacionamento individual/muitos o tempo todo lá dentro

2) Qual é a maneira mais simples de corrigir isso além de adicionar outra chave e acabar com o conceito de chave primária compartilhada?

Muito obrigado

Foi útil?

Solução

foo_id são a chave primária para as duas mesas respectivas

Você não pode ter entradas duplicadas para um PK com o MS SQL Server ou o Oracle, por isso cometeu um erro em algum lugar. Você pode ter configurado o relacionamento FK no SQL Server, mas não há como você definir foo_id dentro T_FooBodys como um PK e ainda permitia entradas duplicadas.

Outras dicas

Se Foo_id for a chave primária na tabela T_FOOBODYS, ela deve ser única. Parece que você deseja que o Foo_Id seja uma chave estrangeira no T_FOOBODYS. Eu acho que o SQL Server tem a mesma restrição - que uma chave primária deve ser única - essa é basicamente a definição de uma chave primária.

Você pode adicionar um novo PK à tabela Bodys? E deixe Foo_id como o PK na mesa de cabeçalho e uma chave estrangeira na tabela Bodys?

  1. Não acredito que tenha funcionado como você descreve no MS SQL Server. Se você tivesse uma restrição de chave primária em T_FooBodys.foo_id, então você pode inserir apenas uma linha com um determinado valor.

  2. Fazer T_FooBodys aceitar várias linhas para um determinado valor de foo_id, você deve adicionar outra coluna e fazer uma chave primária de duas colunas sobre foo_id com essa nova coluna. Isso permitirá que você tenha valores distintos na segunda coluna, preservando a singularidade.

    CREATE TABLE T_FooBodys (
      foo_id INTEGER NOT NULL,
      foo_body_id INTEGER NOT NULL,
      foobody TEXT,
      PRIMARY KEY (foo_id, foo_body_id),
      FOREIGN KEY (foo_id) REFERENCES T_Foo (foo_id)
    );
    

Para responder a determinado problema, direi:

  1. Não sei sobre o MSSQL, mas o Oracle é rigoroso para a chave estrangeira e a chave primária. Para adicionar alguma chave estrangeira, você precisa ter certeza de que esse ID já existe na tabela primária. Se essa chave primária não existir, você receberá a restrição ORA-xxx violada. Semelhante à chave estrangeira, a principal restrição de chave precisa que seu valor seja único. Quando algo não é exclusivo é inserido como chave primária, você recebe a chave primária do ORA-XXX violada. Não tenho certeza se o MSSQL é tão rigoroso quanto o Oracle ou não. Mas no MySQL, esse tipo de situação pode ser evitado usando algum mecanismo que não é "muito rigoroso" (em restrição de chave estrangeira).
  2. Para lidar com isso, você pode fazer várias coisas. Primeiro, não misture a chave primária e a chave estrangeira no mesmo campo. Ajuda quando você os separa. Basta deixar a chave primária aumentar toda vez que você inserir e garantir que a chave estrangeira (em outro campo) não quebre nenhuma restrição. Segundo, você pode manter esse conceito de "campo multifuncional" usando apenas um campo. Mas, para fazer isso, você precisa remover a restrição de chave primária deste campo multifuncional. Portanto, produz uma tabela sem chave primária. Não tenho muita certeza disso, já que não tenho mais acesso ao Oracle Database. Alguém por favor confirme isso.
  3. Afinal, usar o relacionamento 1-1 é como fornecer provas de que você projeta incorretamente a estrutura da sua tabela. Porque, como todos sabem, o relacionamento 1-1 pode ser simplificado em uma única tabela.

Espero que ajude

Você deve trocar a tabela T_FOOBODYS Da seguinte maneira:

/*Create table*/
create table T_FOOBODYS  
(  
  FOOBODY_ID NUMBER(10) not null,  
  FOO_ID     NUMBER(10) not null,  
  FOOBODY    VARCHAR2(512)  
);

/* Create/Recreate primary, unique and foreign key constraints */
alter table FOOBODY  
  add constraint FBPK primary key (FOOBODY_ID)  
  ENABLE;  
alter table FOOBODY  
  add constraint FBFK foreign key (FOO_ID)  
  references T_FOO(FOO_ID);

Aqui, FOOBODY_ID significa sua chave primária para o seu T_FOOBODYS mesa e FOO_ID é uma restrição de referência a T_FOO.

O RedFilter respondeu à pergunta sobre por que você está recebendo o erro. Gostaria de saber por que as duas tabelas são separadas: parece que há um relacionamento de 1 a 1, e o cabeçalho e o corpo devem estar na mesa principal. A única razão para não fazer isso seria se houvesse uma consideração de desempenho.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top