2012-09-05

pechkin: (Default)
2012-09-05 11:22 am
Entry tags:

SQL - вопрос

Есть такая таблица, для связей объектов, и в ней два поля, куда вписываются id объектов. Нужны такие ограничения:

1. Нельзя привязать объект сам к себе: ALTER TABLE [dbo].[Relations] ADD CHECK (GUID1 <> GUID2)
2. Нельзя привязать один объект к другому больше, чем один раз: CREATE UNIQUE INDEX [GUIDsUnique] ON [dbo].[Relations]
([GUID1] ASC, [GUID2] ASC) 
3. Нельзя привязать один объект к другому, если другой уже привязан к первому. Как это реализовать на уровне базы данных?
4. Не забыл ли я чего?
UPD: Видимо, я сделаю так: 

-- проверка привязки объекта к себе самому
ALTER TABLE [dbo].[Relations] ADD CHECK (GUID1 <> GUID2)
-- проверка повторной привязки 
CREATE UNIQUE INDEX [GUIDsUnique] ON [dbo].[Relations] ([GUID1] ASC, [GUID2] ASC) 
-- триггер на добавление/изменение, который просто уберет из таблицы все (максимум одну) перевернутые пары. Они ведь по смыслу совершенно идентичны той, которая только что появилась

Я не ошибся нигде?

UPD: еще чуть более элегантное решение: не надо что-то делать, если не надо это делать:

ALTER TRIGGER [dbo].[CheckReversedPairs_Insert]
ON [dbo].[Call_Related]
INSTEAD OF INSERT
AS
BEGIN
if 0 = (select count(*)
    from call_related, inserted 
    where call_related.callguid1=inserted.callguid2 and call_related.callguid2=inserted.callguid1)
insert into call_related 
    select * from inserted
END

Осталось только сочинить запрос, который проверит существующую уже таблицу на перевернутые пары. Делов-то. И обедать.

UPD: Сытое брюхо подсказало выход:

SELECT Call_Related.*
FROM     Call_Related INNER JOIN
                  Call_Related AS Call_Related_1 ON Call_Related.CallGUID1 = Call_Related_1.CallGUID2 AND Call_Related.CallGUID2 = Call_Related_1.CallGUID1 AND 
                  Call_Related.CallGUID1 < Call_Related.CallGUID2