【问题标题】:Nullable Foreign Key Constraints可空外键约束
【发布时间】:2012-01-24 21:47:10
【问题描述】:

我们正在尝试增加 Web 应用程序的数据库兼容性范围。我们的应用程序是带有 JSP、Servlet 和 EJB 的 Java EE。我们试图让我们的应用程序兼容的数据库是 SQL Server 2008。

我们遇到的问题是,我们的应用程序在很多情况下在很多文件中都使用了可为空的外键。这些可为空的外键在其他数据库中工作,但我们还没有找到让它们在 SQL Server 2008 中工作的方法,因为它只允许单个外键在给定时间为“空”。我们知道,一般来说,最好避免这种可以为空的外键。但是,这个 Web 应用程序很大,很难一个一个地更改文件。

到目前为止,我们已经尝试了以下方法:
[1] 初始化引用表中的虚拟元素,以便外键指向某些东西。
[2] 使用 'EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"' 来移除外键约束

不幸的是,在上述 [1] 中初始化虚拟元素破坏了 Web 应用程序中的许多组件。

不幸的是,尝试根据上面 [2] 中的语句删除约束没有奏效。我们怀疑这是因为随后尝试删除每个表会导致外键约束错误。

目前,对以下问题的明确回答将有助于我们取得一些进展:
[1] 是否有一种快速修复方法可以让 SQL Server 2008 允许多个“空”值外键?
[2] 我们是否可以尝试另一种不涉及对 Web 应用程序进行大量更改的解决方法?

【问题讨论】:

  • CREATE TABLE A(X INT NULL UNIQUE);CREATE TABLE B(X INT NULL REFERENCES A(X));INSERT INTO B VALUES (NULL),(NULL) 工作正常,所以大概您是在谈论对表 A 中多个空值的限制?

标签: java sql-server sql-server-2008 jakarta-ee foreign-keys


【解决方案1】:

我不确定你在说什么!如果您发布了示例架构,我可能会理解您的意思。

一个表中可以有多个空外键列

构建表和 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

【讨论】:

  • 父表中不能有多个 Null,我认为这可能是他的问题。
猜你喜欢
  • 2017-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-17
  • 2017-04-20
  • 2018-03-05
  • 2013-01-30
  • 2014-01-16
相关资源
最近更新 更多