alexeyvg |
asvMan | Приведу пример. Есть 3 таблицы, А, B, C. C ссылается на B, B на А. Теперь, в А удаляем запись, соответственно, удаляются в B, а затем и в C. Что произойдет, если где-то в середине этой цепочки возникнет ошибка? Изменения откатятся во всех таблицах? | Нет, но это не нарушает целостности. Она нарушится, если мы удалим записи в А, а в B и C останутся. |
Разве эти Ваши фразы не противоречат друг другу?
Ребята, а что нам мешает проделать маленький опыт?
SET NOCOUNT ON;
USE tempdb;
IF OBJECT_ID(N'F2','U') IS NOT NULL DROP TABLE F2;
IF OBJECT_ID(N'F1','U') IS NOT NULL DROP TABLE F1;
IF OBJECT_ID(N'T','U') IS NOT NULL DROP TABLE T;
GO
CREATE TABLE T(ID INT NOT NULL IDENTITY CONSTRAINT pkT PRIMARY KEY(ID));
GO
CREATE TABLE F1
(
ID INT NOT NULL IDENTITY CONSTRAINT pkF1 PRIMARY KEY(ID),
IDT INT CONSTRAINT fkF1T FOREIGN KEY(IDT) REFERENCES T(ID) ON DELETE CASCADE);
GO
CREATE TABLE F2
(
ID INT NOT NULL IDENTITY CONSTRAINT pkF2 PRIMARY KEY(ID),
IDF1 INT CONSTRAINT fkF2F1 FOREIGN KEY(IDF1) REFERENCES F1(ID) ON DELETE CASCADE);
GO
CREATE TRIGGER tdF2 ON F2 FOR DELETE AS RAISERROR('Опаньки!',16,0);
GO
INSERT T DEFAULT VALUES;
INSERT T DEFAULT VALUES;
GO
INSERT F1(IDT) SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 2;
GO
INSERT F2(IDF1) SELECT 1 UNION ALL SELECT 3;
GO
/*
DISABLE TRIGGER ALL ON F2;
ENABLE TRIGGER ALL ON F2;
SET XACT_ABORT OFF;
*/
DELETE T WHERE ID=1;
GO
SELECT * FROM T;
SELECT * FROM F1;
SELECT * FROM F2;
GO
IF OBJECT_ID(N'F2','U') IS NOT NULL DROP TABLE F2;
IF OBJECT_ID(N'F1','U') IS NOT NULL DROP TABLE F1;
IF OBJECT_ID(N'T','U') IS NOT NULL DROP TABLE T;
GO
Можно ещё поиграться с содержимым комментария.
Но REFERENSIAL INTEGRITY всё равно не может нарушаться при живых FOREIGN KEYs!