Как вставить новую запись в таблицу A, когда таблица A зависит от таблицы B, и наоборот - PullRequest
0 голосов
/ 06 мая 2009

Я не уверен, что это хорошо продумано, если нет, посоветуйте мне, как это сделать.

  • Я использую Sql Server 2008

У меня есть:

TableA (TableA_ID int identity PK, Value varchar(10), TableB_ID PK not null)
TableB (TableB_ID int identity PK, Value varchar(10), TableA_ID PK not null)

Цель проста:

  • TableA может иметь строки, только если в TableB есть хотя бы 1 строка, связанная с TableA;
  • И для каждой строки в TableB должна быть строка, связанная с ней в TableA);

TableA - это «Родительская таблица», а TableB - «Детская таблица», это что-то вроде: родитель должен иметь 1 или более детей, а у каждого ребенка может быть только 1 родитель.

Это правильно?

Проблема, с которой я сталкиваюсь, заключается в том, что, когда я пытаюсь сделать инструкцию INSERT, если это правильно, как мне сделать INSERT? временно отключить ограничения?

Спасибо!

Проблема у меня возникает, когда я пытаюсь вставить

Ответы [ 5 ]

1 голос
/ 06 мая 2009
TableA (TableA_ID int identity PK, Value varchar(10))
TableB (TableB_ID int identity PK, Value varchar(10), TableA_ID not null)

как родитель, таблица a не должна ссылаться на таблицу b, так как для таблицы be требуется поле в таблице a. это называется отношения один ко многим.

поэтому в таблице а вы можете иметь следующие значения:

1 a
2 b
3 c

и в таблице b вы могли бы иметь эти:

1 asdf 1
2 sdfg 1
3 pof 2
4 dfgbsd 3

теперь вы можете сделать запрос для отображения данных из таблицы a с помощью:

select b.TableB_ID, b.Value, a.TableA_ID, a.Value
from TableB b
inner join TableA
on b.TableA_ID=a.TableA_ID
0 голосов
/ 18 июня 2009

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

Этого можно достичь, сделав уровень изоляции SERIALIZABLE, но это, в свою очередь, может помешать вашему параллелизму.

Кев

0 голосов
/ 06 мая 2009

Это необычное требование. Если бы я застрял с этим (и я бы действительно отодвинулся, чтобы убедиться, что это действительно было требованием), я разработал бы это следующим образом:

Создайте обычный внешний ключ из таблицы a в таблицу b с родительским элементом и b с дочерним.

Добавить триггер в таблицу a, который вставляет запись в таблицу b, если она не существует, когда в таблицу вставляется запись. Добавьте еще один триггер в таблицу b, который удаляет в таблице запись, если последняя связанная запись в таблице b удалена.

В качестве альтернативы, вы можете поместить вставки в обе таблицы в хранимой процедуре. Удалите все права на вставку в таблицу, кроме как через процедуру. Вам по-прежнему потребуется отношение внешнего ключа от таблицы a к таблице b и триггер для таблицы b, чтобы гарантировать, что при удалении последней записи в таблице запись будет удалена. Но в этом случае вы могли бы покончить с триггером на столе.

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

0 голосов
/ 06 мая 2009

У вас круговая зависимость. Это не очень хорошо работает для декларативного применения, вам придется отключать ограничения каждый раз, когда вы хотите вставить.

0 голосов
/ 06 мая 2009

Родители не зависят от детей. Вам необходимо удалить ссылку на таблицу B в таблице A.

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