Перекрестные ссылки
От: varenikAA  
Дата: 22.04.20 09:13
Оценка:
Туплю
сделал таблицу
Create Table Client (id int primary key, name nvarchar(max))

Create Table Contact(id int primary key, name nvarchar(max), ClientId int, constraint FK_Contact_Client foreign key (ClientId) references Client(Id))

Alter Table Client add ContactId int, constraint FK_Client_Contact foreign key (ContactId) references Contact(Id)


Вставка ни в одну таблицу не работает если, обе записи новые.

The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Client_Contact". The conflict occurred in table "dbo.Contact", column 'Id'.


Нельзя такие ограничения использовать?
С тчк зрения ООП вроде все корректно.
Нужно только вставку сделать в одну таблицу до того как у второй появится значение первичного ключа.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re: Перекрестные ссылки
От: Mihas  
Дата: 22.04.20 09:36
Оценка:
Здравствуйте, varenikAA, Вы писали:

AA>Нужно только вставку сделать в одну таблицу до того как у второй появится значение первичного ключа.

Попробуй сделать поле Client.ContackId null. И не создавай клиента до контакта.
Re: Перекрестные ссылки
От: Dym On Россия  
Дата: 22.04.20 09:36
Оценка: +1
Здравствуйте, varenikAA, Вы писали:

AA>Нельзя такие ограничения использовать?

AA>С тчк зрения ООП вроде все корректно.
AA>Нужно только вставку сделать в одну таблицу до того как у второй появится значение первичного ключа.
А словами описать можешь, что нужно получить?
Счастье — это Glück!
Re[2]: Перекрестные ссылки
От: wildwind Россия  
Дата: 22.04.20 10:04
Оценка:
Здравствуйте, Dym On, Вы писали:

DO>А словами описать можешь, что нужно получить?


Главный вопрос — каковы отношения между контактами и клиентами?
Re: Перекрестные ссылки
От: torvic Голландия  
Дата: 22.04.20 10:10
Оценка: +1
Здравствуйте, varenikAA, Вы писали:

AA>Alter Table Client add ContactId int, constraint FK_Client_Contact foreign key (ContactId) references Contact(Id)

зачем нужен референс Client -> Contact? Contact -> Client достаточен
Re[2]: Перекрестные ссылки
От: varenikAA  
Дата: 22.04.20 10:11
Оценка:
Здравствуйте, Dym On, Вы писали:

DO>Здравствуйте, varenikAA, Вы писали:


AA>>Нельзя такие ограничения использовать?

AA>>С тчк зрения ООП вроде все корректно.
AA>>Нужно только вставку сделать в одну таблицу до того как у второй появится значение первичного ключа.
DO>А словами описать можешь, что нужно получить?

Открываем карту клиента,
на вкладке контакт выбирает из таблицы персоны запись в качестве контакта,
в карту клиента записываем айди контакта как контакт по умолчанию, в таблице контакты должна быть запись
многих контактов, в таблице клиент храним ссылку на основной контакт, получается не может сохранить одно
не сохранив другого из-за нарушения ссылочной целостности.
Пока удалил внешний ключ и клиентов. Второе решение как мне думается использовать аттрибут "основной" в таблице контактов.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[2]: Перекрестные ссылки
От: varenikAA  
Дата: 22.04.20 10:12
Оценка:
Здравствуйте, Mihas, Вы писали:

M>Здравствуйте, varenikAA, Вы писали:


AA>>Нужно только вставку сделать в одну таблицу до того как у второй появится значение первичного ключа.

M>Попробуй сделать поле Client.ContackId null. И не создавай клиента до контакта.

К сожалению, такой вариант не пройдет, т.к. контакт ссылается на клиента(ограничение целостности).
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[3]: Перекрестные ссылки
От: Mihas  
Дата: 22.04.20 10:25
Оценка:
Здравствуйте, varenikAA, Вы писали:

M>>Попробуй сделать поле Client.ContackId null. И не создавай клиента до контакта.

AA>К сожалению, такой вариант не пройдет, т.к. контакт ссылается на клиента(ограничение целостности).
Ну и пусть ссылается, когда появится. Не пойму, чем мешает?
Я может не так выразился. Я имел в виду, поле Client.ContactId должно быть nullable.
Re[3]: Перекрестные ссылки
От: Dym On Россия  
Дата: 22.04.20 11:09
Оценка:
Здравствуйте, varenikAA, Вы писали:

AA>Открываем карту клиента,

AA>на вкладке контакт выбирает из таблицы персоны запись в качестве контакта,
AA>в карту клиента записываем айди контакта как контакт по умолчанию, в таблице контакты должна быть запись
AA>многих контактов, в таблице клиент храним ссылку на основной контакт, получается не может сохранить одно
AA>не сохранив другого из-за нарушения ссылочной целостности.
AA>Пока удалил внешний ключ и клиентов. Второе решение как мне думается использовать аттрибут "основной" в таблице контактов.
Пока каша. Из этого описания можно выделить сущности "Карта клиента", "Клиент", "Контакт", "Персона" — это разные сущности?

Какое отношение между "Клиентами" и "Контактами"? 1-1, 1-n, n-n?

Пока не понятно, но подозреваю, что должно быть как-то так:
create table Client(
  id integer primary key
, name ...
);

create table Contact(
  id integer primary key
, name ...
);

create table ClientContact(
  client_id integer 
, contact_id integer 
, is_main boolean
...
, constraint fk_cc_client foreign key (client_id) references Client(id)
, constraint fk_cc_contact foreign key (contact_id) references Contact(id)
);
Счастье — это Glück!
Re: Перекрестные ссылки
От: Milena США  
Дата: 22.04.20 13:53
Оценка: +2
Здравствуйте, varenikAA, Вы писали:

AA>Туплю

AA>сделал таблицу
AA>
AA>Create Table Client (id int primary key, name nvarchar(max))

AA>Create Table Contact(id int primary key, name nvarchar(max), ClientId int, constraint FK_Contact_Client foreign key (ClientId) references Client(Id))

AA>Alter Table Client add ContactId int, constraint FK_Client_Contact foreign key (ContactId) references Contact(Id)
AA>


AA>Вставка ни в одну таблицу не работает если, обе записи новые.


AA>Нельзя такие ограничения использовать?


Нельзя.

AA>Нужно только вставку сделать в одну таблицу до того как у второй появится значение первичного ключа.


Я так понимаю, что цель "у одного клиента много контактов, и у одного контакта много клиентов", тогда это связь "многие-ко-многим" и такое делается через третью таблицу cross-reference table, которая ссылается на обе исходных и хранит каждую из многих связей.
Если цель иерархия "у одного клиента есть мастер-контакт, к которому привязаны дополнительные клиенты", тогда надо делать иерархическую таблицу и внешние ключи будут ссылаться не перекрестно.
Re[4]: Перекрестные ссылки
От: varenikAA  
Дата: 22.04.20 23:53
Оценка:
Здравствуйте, Mihas, Вы писали:

M>Здравствуйте, varenikAA, Вы писали:


M>>>Попробуй сделать поле Client.ContackId null. И не создавай клиента до контакта.

AA>>К сожалению, такой вариант не пройдет, т.к. контакт ссылается на клиента(ограничение целостности).
M>Ну и пусть ссылается, когда появится. Не пойму, чем мешает?
M>Я может не так выразился. Я имел в виду, поле Client.ContactId должно быть nullable.

Пока так и сделал — удалил ограничение из таблицы Client.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[4]: Перекрестные ссылки
От: varenikAA  
Дата: 22.04.20 23:57
Оценка:
Здравствуйте, Dym On, Вы писали:

DO>Здравствуйте, varenikAA, Вы писали:


AA>>Открываем карту клиента,

AA>>на вкладке контакт выбирает из таблицы персоны запись в качестве контакта,
AA>>в карту клиента записываем айди контакта как контакт по умолчанию, в таблице контакты должна быть запись
AA>>многих контактов, в таблице клиент храним ссылку на основной контакт, получается не может сохранить одно
AA>>не сохранив другого из-за нарушения ссылочной целостности.
AA>>Пока удалил внешний ключ и клиентов. Второе решение как мне думается использовать аттрибут "основной" в таблице контактов.
DO>Пока каша. Из этого описания можно выделить сущности "Карта клиента", "Клиент", "Контакт", "Персона" — это разные сущности?

DO>Какое отношение между "Клиентами" и "Контактами"? 1-1, 1-n, n-n?


DO>Пока не понятно, но подозреваю, что должно быть как-то так:

DO>
create table Client(
DO>  id integer primary key
DO>, name ...
DO>);

DO>create table Contact(
DO>  id integer primary key
DO>, name ...
DO>);

DO>create table ClientContact(
DO>  client_id integer 
DO>, contact_id integer 
DO>, is_main boolean
DO>...
DO>, constraint fk_cc_client foreign key (client_id) references Client(id)
DO>, constraint fk_cc_contact foreign key (contact_id) references Contact(id)
DO>);
DO>

Да 1-n, спасибо за подробный пример, у меня только is_main выполняет поле Client.ContactId(убрал на нем ограничение). Если использовать is_main то, нужно не забывать при смене основного контакта менять флаг у остальных.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[5]: Перекрестные ссылки
От: wildwind Россия  
Дата: 23.04.20 05:58
Оценка:
Здравствуйте, varenikAA, Вы писали:

M>>Я может не так выразился. Я имел в виду, поле Client.ContactId должно быть nullable.


AA>Пока так и сделал — удалил ограничение из таблицы Client.


Ты не понял совета. Ограничение FK должно работать только, когда Client.ContactId заполнено.
Re: Перекрестные ссылки
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 23.04.20 06:16
Оценка:
Здравствуйте, varenikAA, Вы писали:

AA>Туплю

AA>сделал таблицу
AA>
AA>Create Table Client (id int primary key, name nvarchar(max))

AA>Create Table Contact(id int primary key, name nvarchar(max), ClientId int, constraint FK_Contact_Client foreign key (ClientId) references Client(Id))

AA>Alter Table Client add ContactId int, constraint FK_Client_Contact foreign key (ContactId) references Contact(Id)
AA>


AA>Вставка ни в одну таблицу не работает если, обе записи новые.


AA>Нельзя такие ограничения использовать?

AA>С тчк зрения ООП вроде все корректно.
AA>Нужно только вставку сделать в одну таблицу до того как у второй появится значение первичного ключа.

Здесь две вещи:
1. Люди
2. Связи между людьми

Вот и оформи эти две вещи в виде двух таблиц.

Связь между двумя человеками будет представлена тремя записями. Две в первой таблице и одна во второй.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[6]: Перекрестные ссылки
От: varenikAA  
Дата: 23.04.20 08:57
Оценка:
Здравствуйте, wildwind, Вы писали:

W>Здравствуйте, varenikAA, Вы писали:


M>>>Я может не так выразился. Я имел в виду, поле Client.ContactId должно быть nullable.


AA>>Пока так и сделал — удалил ограничение из таблицы Client.


W>Ты не понял совета. Ограничение FK должно работать только, когда Client.ContactId заполнено.


Разве в sql server и вообще можно ставить ограничение на поле с NULL, ведь по логике в контактах тогда должна быть запись ключом NULL?
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[7]: Перекрестные ссылки
От: wildwind Россия  
Дата: 23.04.20 09:07
Оценка:
Здравствуйте, varenikAA, Вы писали:

AA>Разве в sql server и вообще можно ставить ограничение на поле с NULL,


Можно.

AA>в контактах тогда должна быть запись ключом NULL?


Нет. NULL это не какое-то особое значение, это отсутствие значения. И ключом NULL быть не может.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.