Обнуляемые ограничения внешнего ключа - PullRequest
0 голосов
/ 25 января 2012

Мы пытаемся увеличить объем совместимости базы данных для нашего веб-приложения.Наше приложение - Java EE с JSP, сервлетами и EJB.База данных, с которой мы пытаемся сделать наше приложение совместимым, - это SQL Server 2008.

Проблема, с которой мы сталкиваемся, заключается в том, что наше приложение во многих случаях использует обнуляемые внешние ключи во многих файлах.Эти обнуляемые внешние ключи работают в других базах данных, но мы не нашли способа заставить их работать в SQL Server 2008, потому что это позволит только одному внешнему ключу быть «нулевым» в данный момент времени.Мы понимаем, что, вообще, лучше избегать таких внешних ключей, которые могут быть недействительными.Тем не менее, это веб-приложение имеет большой размер, и было бы довольно сложно менять файлы по одному.

До сих пор мы пробовали следующее:
[1] инициализировали фиктивные элементы в ссылочных таблицах, такчто внешние ключи будут указывать на что-то.
[2] с использованием 'EXEC sp_msforeachtable "ALTER TABLE? NOCHECK CONSTRAINT all"', чтобы удалить ограничение внешнего ключа

К сожалению, инициализация фиктивных элементов в [1] выше сломал много компонентов в веб-приложении.

К сожалению, попытка снять ограничение в соответствии с утверждением в [2] выше не сработала.Мы подозреваем, что это потому, что последующие попытки удалить каждую таблицу приводят к ошибкам ограничения внешнего ключа.

В настоящее время четкие ответы на следующие вопросы помогут нам добиться определенного прогресса:
[1] Есть ли быстрое решение проблемы?разрешить SQL Server 2008 разрешать использование нескольких внешних ключей с нулевым значением?
[2] Есть ли еще один обходной путь, который не потребует значительных изменений в нашем веб-приложении?

1 Ответ

0 голосов
/ 25 января 2012

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

В таблице может быть несколько пустых столбцов FK :

построить таблицы и ФК:

CREATE TABLE dbo.AAAA
    (
    A_ID int NOT NULL identity(1,1) primary key,
    B_ID int NULL,
    C_ID int NULL
    )  ON [PRIMARY]

CREATE TABLE dbo.BBBB
    (
    B_ID int NOT NULL identity(1,1) primary key,
    A_ID int NULL,
    C_ID int NULL
    )  ON [PRIMARY]

CREATE TABLE dbo.CCCC
    (
    C_ID int NOT NULL identity(1,1) primary key,
    A_ID int NULL,
    B_ID int NULL
    )  ON [PRIMARY]


ALTER TABLE dbo.CCCC ADD CONSTRAINT FK_CCCC_AAAA FOREIGN KEY ( A_ID ) REFERENCES dbo.AAAA ( A_ID ) ON UPDATE  NO ACTION  ON DELETE  NO ACTION 
ALTER TABLE dbo.BBBB ADD CONSTRAINT FK_BBBB_AAAA FOREIGN KEY ( A_ID ) REFERENCES dbo.AAAA ( A_ID ) ON UPDATE  NO ACTION  ON DELETE  NO ACTION 
ALTER TABLE dbo.CCCC ADD CONSTRAINT FK_CCCC_BBBB FOREIGN KEY ( B_ID ) REFERENCES dbo.BBBB ( B_ID ) ON UPDATE  NO ACTION  ON DELETE  NO ACTION 
ALTER TABLE dbo.AAAA ADD CONSTRAINT FK_AAAA_BBBB FOREIGN KEY ( B_ID ) REFERENCES dbo.BBBB ( B_ID ) ON UPDATE  NO ACTION  ON DELETE  NO ACTION 
ALTER TABLE dbo.AAAA ADD CONSTRAINT FK_AAAA_CCCC FOREIGN KEY ( C_ID ) REFERENCES dbo.CCCC ( C_ID ) ON UPDATE  NO ACTION  ON DELETE  NO ACTION 
ALTER TABLE dbo.BBBB ADD CONSTRAINT FK_BBBB_CCCC FOREIGN KEY ( C_ID ) REFERENCES dbo.CCCC ( C_ID ) ON UPDATE  NO ACTION  ON DELETE  NO ACTION 

вставить пример данных:

INSERT INTO AAAA VALUES (NULL,NULL)
INSERT INTO AAAA VALUES (NULL,NULL)
INSERT INTO AAAA VALUES (NULL,NULL)

INSERT INTO BBBB VALUES (1,NULL)
INSERT INTO BBBB VALUES (2,NULL)
INSERT INTO BBBB VALUES (NULL,NULL)
INSERT INTO BBBB VALUES (NULL,NULL)
INSERT INTO BBBB VALUES (1,NULL)

Показать данные (посмотрите, сколько столбцов FK равно нулю):

select * from AAAA
select * from BBBB
select * from CCCC

ВЫВОД:

A_ID        B_ID        C_ID
----------- ----------- -----------
1           NULL        NULL
2           NULL        NULL
3           NULL        NULL

(3 row(s) affected)

B_ID        A_ID        C_ID
----------- ----------- -----------
1           1           NULL
2           2           NULL
3           NULL        NULL
4           NULL        NULL
5           1           NULL

(5 row(s) affected)

C_ID        A_ID        B_ID
----------- ----------- -----------

(0 row(s) affected)

Если это не то, о чем вы говорите, вам нужно предоставить несколько примеров таблиц и данных.

удалить эти тестовые таблицы:

ALTER TABLE dbo.CCCC drop CONSTRAINT FK_CCCC_AAAA
ALTER TABLE dbo.BBBB drop CONSTRAINT FK_BBBB_AAAA
ALTER TABLE dbo.CCCC drop CONSTRAINT FK_CCCC_BBBB
ALTER TABLE dbo.AAAA drop CONSTRAINT FK_AAAA_BBBB
ALTER TABLE dbo.AAAA drop CONSTRAINT FK_AAAA_CCCC
ALTER TABLE dbo.BBBB drop CONSTRAINT FK_BBBB_CCCC
drop table AAAA
drop table BBBB
drop table CCCC
...