7

在数据库迁移期间,我遇到了以下形式的数据库表约束:

ALTER TABLE [dbo].[myTable]
ADD CONSTRAINT [someName] FOREIGN KEY ([id]) REFERENCES [dbo].[myTable] ([id])
ON DELETE NO ACTION
ON UPDATE NO ACTION

为什么要这样做?这最初是在 Sybase 数据库上完成的,我们正在转换为 SQL Server 2008 R2。

更新:是的,外键约束是引用同一个表和相同字段的字段。

我在源 Sybase 数据库上运行了这个查询,发现定义了 42 个这些疯狂的键,所以它看起来不像是错字。

SELECT sr.constrid as [Constraint ID],
       so.name as [Table],
       sc.name as [Column]
  FROM sysreferences sr
       INNER JOIN sysobjects so ON (so.id = sr.tableid)
       INNER JOIN syscolumns sc ON (sc.id = sr.tableid AND sc.colid = sr.fokey1)
 WHERE sr.tableid = sr.reftabid
   AND sr.fokey1 = sr.refkey1
   AND sr.fokey2 = 0
   AND sr.refkey2 = 0
4

4 回答 4

2

I believe that hierarchies are the standard examples you'll find in books whenever you use foreign keys for the same table, such as:

create table Employees (
 EmployeeID int identity primary key,
 EmployeeName varchar(50),
 ManagerID int
 Foreign key (managerID) references Employees(EmployeeID)
)

What you posted looks like a wrong application of this hierarchy relation in the same table. I'm not entirely sure why you'd ever wanna do that.

Hope this helped =)

于 2012-10-18T21:59:05.387 回答
1

Surprise! This totally works:

create table crazy (
    ID int primary key references crazy (ID) -- This runs
);
insert into crazy select 1;  -- So does this
select * from crazy; -- Returns 1
truncate table crazy; -- Works just fine

I can only think that this would have been a mistake (Typo? Dragging a column onto itself in a diagram?) or used to fool another system (ORM?) into some particular behavior. I will be very curious to see if someone comes up with a legit reason.

UPDATE: As cleverly suggested by @8kb, this could have been an attempt to prevent truncation, but we can see from my example that even truncation works just fine.

于 2012-10-18T21:59:56.740 回答
0

我猜这是数据库模型中的错误。

这真的很奇怪。我无法想象这种结构有什么有用的目的。

插入数据的唯一方法是不检查引用完整性。这意味着使用明确禁用的引用或使用某种批量插入等。

于 2012-10-18T21:50:54.460 回答
0

引用自身的外键列的效果似乎没什么。至于为什么数据库引擎会让你做这种无用的事情,这仍然是一个悬而未决的问题。

但是,我相信有人会像这样构建外键的原因是懒惰/粗心。我发现在 SQL Server Management Studio 中,如果您使用 GUI 构建外键(而不是在 T-SQL 中写出来),SSMS 的初始行为是像在这个问题中一样创建外键:

  1. 在“对象资源管理器”窗格中展开数据库的任何表。我们将此表称为TableA。
  2. 右键单击 TableA 节点下的 Keys 并选择 New Foreign Key... 这将打开 Modify table 窗格和 Foreign Key Relationships 对话框。
  3. 什么都不做,只需单击外键关系对话框上的关闭按钮。 “糟糕,我不是故意要添加外键的。”
  4. 关闭对话框仍然会生成一个名为 FK_TableA_TableA 的外键,并选择主键列作为基础列和参考列。
  5. 在“修改表”窗格仍处于打开状态(关闭“外键关系”对话框后仍处于打开状态)的情况下,将其关闭。它有变化(你刚刚创建的新外键)。保存这些更改。
  6. TableA 的数据库中现在存在一个新的外键,主键列引用它自己。
于 2014-06-05T16:05:47.927 回答