Проблема со связкой таблиц(MS SQL 6,5).
Эдуард Валеев
Дата: 14.05.2000 08:11:32
Уважаемые Господа!
Плис, помогите начинающему....
У меня такая проблема.
Существует 2 таблицы, скажем <aa> и <bb>;
У обеих есть поля id(значения в них уникальны в рамках одной таблицы)
Существует третья таблица <cc>
В которой есть поле "ObjectsIds", которое хранит значения id из первых двух таблиц.
Существует диаграмма связей, из которой ясно, что
в поле ObjectsIds могут находиться только значения из таблиц <aa> и <bb>. Привязка один-ко мнеогим.
так вот банальный пример(генерящий ошибку):
В таблице <aa>, допустим, 5 записей (id:1,2,3,4,5)
в таблице <bb> - 3 записи (id:1,2,3)
При записи в таблицу <cc> записи с ObjectsIds, скажем 4 [SQL естесственно проверяет наличие такового в таблице <aa> и <bb>] выдаётся ошибка:
INSERT statement conflicted with COLUMN FOREIGN KEY constraint 'FK_cc_bb'. The conflict occurred in database 'TestDataBase', table 'bb', column 'id'
Насколько я понимаю, серверу не нравится то, что
id под номером 4 отсутствует в таблице <bb>
Так вот, я скорее всего не правильно ставлю задачу, но в конце-концов, мне хотелось бы избежать подобной проблемы. Короче говоря, чтобы в таблицу <cc> ложились данные, присутствующие _хотябы_в_одной_из таблиц_(но не обязательно строго в обоих)....
Есть ли возможность решить такую проблему наиболее корректным способом?
Заранее благодарен. Эдик
judge
Дата: 14.05.2000 08:12:48
Для поддержания целостности данных, при отсутствии возможности использовать ключи Microsoft рекомендует использовать триггеры.
Для удобства еще можно создать view, который будет отображать все доступные ID's из этих таблиц. Должно получиться что-то типа:
------------------------
CREATE VIEW <vvv>
AS
SELECT DISTINCT <ObjectsID_Col>
FROM <aa>
UNION
SELECT DISTINCT <ObjectsID_Col>
FROM <bb>
------------------------
CREATE TRIGGER cc_val_trg
ON <cc>
FOR INSERT, UPDATE
AS
IF UPDATE(<ObjectsID_Col>)
IF EXISTS (SELECT 1 FROM <vvv>, inserted
WHERE <vvv>.<ObjectsID_Col> <> inserted.<ObjectsID_Col>)
RAISERROR('Key violation while inserting data in <cc>', 16, 1)
-------------------
Не забудьте создать еще триггеры на удаление из таблиц <aa>,<bb>, чтобы они проверяли не удаляется ли запись которая используется в <cc>
leonsa
Дата: 14.05.2000 08:14:02
Уважаемые Господа!
У меня вопрос такой:
Как удалить запись в двух связанных таблицах, например, А и B, взаимосвязь один ко многим, если необходимо удалить запись из главной таблицы (ведь триггер срабатывает после изменений в таблице)?
Подскажите, как написать триггер, который мог бы удалять записи в главной таблице.
Заранее благодарен.
judge
Дата: 14.05.2000 08:15:16
Немножко запутанный вопрос.
Если я правильно понял то:
Все удаленные записи хранятся в таблице "deleted", доступной из триггера.
Соответственно если у вас есть главная таблица <master> и связанная <detail> и они связаны например по полю <key_field>, то триггер, удаляющий соответствующие записи в связанной таблице будет выглядеть примерно так:
--------------------------------
CREATE TRIGGER <master>_trg_del
ON <master>
FOR DELETE
AS
DELETE <detail>
FROM deleted d
WHERE <detail>.<key_field> = d.<key_field>
wlad
Дата: 14.05.2000 08:16:50
А никак! Триггер срабатывает только после изменений в таблице - поэтому выход из этой ситуации простой:
1) Либо поддерживать целосность данных только триггерами;
2) Либо поддерживать целосность данных с помощью Foreign Key и ручками стирать данные перед удалением из главной таблицы.
wlad
Дата: 14.05.2000 08:17:39
Спасибо за ответ, именно это я и хотел узнать.
Интересный подход MS SQL к этому вопросу (нет возможности каскадного удаления, обновления.?)
Интересно, как Вы считаете какой из способов более предпочтителен 1-й или 2-й и по какому способу Вы работаете?
Alex
Дата: 15.06.2000 05:25:45
Действительно триггер срабатывает после самого удаления, поэтому его использовать здесь нельзя.
Для каскадного удаления кроме ручек можно использовать хранимые процедуры.