1-> 1 / 1-> N отношения в Oracle? - PullRequest
       70

1-> 1 / 1-> N отношения в Oracle?

0 голосов
/ 31 августа 2010

у меня 2 таблицы

T_Foo
foo_id
fooHeader

T_FooBodys
foo_id
foobody

foo_id - это первичный ключ для обеих соответствующих таблиц. Во второй таблице foo_id - это внешний ключ первой таблицы. Я генерирую PK для обоих табличных значений, используя последовательность, и пытаюсь сделать вставку - один раз в FooHeader и дважды в FooBody.

Мой код падает при второй вставке в t_FooBodys в цикле из-за ошибки "ORA-00001: нарушение уникального ограничения (USERID.FooBodys_PK)"

Итак, у меня есть 2 вопроса:

1) В чем здесь принципиальная разница между MSSQL Server и Oracle? Это отлично работало в SQL Server! У меня все время были отношения один к одному / много

2) Как проще всего это исправить, кроме добавления еще одного ключа и, по сути, прекращения концепции общего первичного ключа?

Большое спасибо

Ответы [ 6 ]

2 голосов
/ 31 августа 2010

foo_id является первичным ключом для обоих их соответствующие таблицы

У вас не может быть повторяющихся записей для ПК с MS SQL Server или Oracle, поэтому вы где-то допустили ошибку. Возможно, вы установили отношение FK в SQL Server, но нет способа установить foo_id в T_FooBodys в качестве PK, и он все еще допускает дублирование записей.

0 голосов
/ 02 сентября 2010

RedFilter ответил на вопрос, почему вы получаете ошибку.Мне интересно, почему эти 2 таблицы разделены: похоже, что есть отношение 1 к 1, а заголовок и тело должны быть в основной таблице.Единственная причина, по которой этого не делать, - это соображения производительности.

0 голосов
/ 31 августа 2010

Вам следует изменить таблицу T_FOOBODYS следующим образом:

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

Здесь FOOBODY_ID обозначает ваш первичный ключ для вашей таблицы T_FOOBODYS, а FOO_ID является ссылочным ограничением.до T_FOO.

0 голосов
/ 31 августа 2010

Чтобы ответить на данную проблему, я скажу:

  1. Я не знаю о MSSQL, но Oracle строго относится к внешнему ключу и первичному ключу. Чтобы добавить некоторый внешний ключ, вы должны быть уверены, что этот идентификатор уже существует в основной таблице. Если этот первичный ключ не существует, вы получите ограничение ORA-xxx нарушено. Подобно внешнему ключу, ограничение первичного ключа должно быть уникальным. Когда что-то не уникальное вставляется в качестве первичного ключа, вы получаете ORA-xxx Первичный ключ нарушен. Я не уверен, что MSSQL так же строг, как Oracle, или нет. Но в MySQL такого рода ситуации можно избежать с помощью некоторого механизма, который не является «слишком строгим» (в ограничении внешнего ключа).
  2. Чтобы справиться с этим, вы можете сделать несколько вещей. Во-первых, не смешивайте первичный ключ и внешний ключ в одном поле. Это помогает, когда вы их разделяете. Просто позвольте первичному ключу увеличиваться каждый раз, когда вы вставляете, и убедитесь, что внешний ключ (в другом поле) не нарушает никаких ограничений. Во-вторых, вы можете поддерживать эту концепцию «многофункционального поля», используя только одно поле. Но для этого вам нужно удалить ограничение первичного ключа из этого многофункционального поля. Следовательно, создайте таблицу без первичного ключа. Я не совсем уверен в этом, так как у меня больше нет доступа к базе данных Oracle. Кто-то, пожалуйста, подтвердите это.
  3. В конце концов, использование отношения 1-1 - это все равно, что доказательство того, что вы неправильно спроектировали структуру таблицы. Потому что, как вы все знаете, отношения 1-1 можно упростить в одну таблицу.

Надеюсь, это поможет

0 голосов
/ 31 августа 2010
  1. Я не верю, что это сработало так, как вы описали в MS SQL Server.Если у вас есть ограничение первичного ключа для T_FooBodys.foo_id, то вы можете вставить только одну строку с заданным значением.

  2. Чтобы T_FooBodys принимала несколько строк для данного значения foo_id, вы должны добавить еще один столбец и сделать первичный ключ из двух столбцов над foo_id с этим новым столбцом.Это позволит вам иметь различные значения во втором столбце, сохраняя уникальность.

    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)
    );
    
0 голосов
/ 31 августа 2010

Если foo_id является первичным ключом в таблице T_FooBodys, то он должен быть уникальным.Похоже, вы хотите, чтобы foo_id был внешним ключом в T_FooBodys.Я бы подумал, что SQL Server имеет такое же ограничение - первичный ключ должен быть уникальным - это в основном определение первичного ключа.

Можете ли вы добавить новый PK в таблицу Bodys?И оставить foo_id как PK в таблице Header и внешний ключ в таблице Bodys?

...