如何在SQL Server 2008中添加引用自身的外键?

end*_*and 3 sql sql-server sql-server-2008

我在网上任何地方都没有看到任何明确,简洁的例子.

使用现有表,如何添加引用此表的外键?例如:

CREATE TABLE dbo.Projects(
    ProjectsID INT IDENTITY(1,1) PRIMARY KEY,
    Name varchar(50)

);
Run Code Online (Sandbox Code Playgroud)

如何编写命令来添加引用同一个表的外键?我可以在一个SQL命令中执行此操作吗?

sta*_*ica 10

我将向您展示几种声明这种外键约束的等效方法.(这个答案是故意重复的,以帮助您识别声明约束的简单模式.)

示例:这是我们希望最终得到的结果:

员工表


情况1:持有外键的列已存在,但尚未声明/尚未强制执行外键关系:

没有声明外键约束的Employee表

在这种情况下,运行此语句:

ALTER TABLE Employee
ADD FOREIGN KEY (ManagerId) REFERENCES Employee (Id);
Run Code Online (Sandbox Code Playgroud)

情况2:表存在,但它还没有外键列:

没有外键列的Employee表

ALTER TABLE Employee
ADD ManagerId INT, -- add the column; everything else is the same as with case 1
    FOREIGN KEY (ManagerId) REFERENCES Employee (Id);
Run Code Online (Sandbox Code Playgroud)

或者更简洁:

ALTER TABLE Employee
ADD ManagerId INT REFERENCES Employee (Id);
Run Code Online (Sandbox Code Playgroud)

案例3:该表尚不存在.

CREATE TABLE Employee -- create the table; everything else is the same as with case 1
(
    Id INT NOT NULL PRIMARY KEY,
    ManagerId INT
);

ALTER TABLE Employee
ADD FOREIGN KEY (ManagerId) REFERENCES Employee (Id);
Run Code Online (Sandbox Code Playgroud)

或者,作为表创建的一部分声明约束内联:

CREATE TABLE Employee
(
    Id INT NOT NULL PRIMARY KEY,
    ManagerId INT,
    FOREIGN KEY (ManagerId) REFERENCES Employee (Id)
);
Run Code Online (Sandbox Code Playgroud)

甚至更简洁:

CREATE TABLE Employee
(
    Id INT NOT NULL PRIMARY KEY,
    ManagerId INT REFERENCES Employee (Id)
);
Run Code Online (Sandbox Code Playgroud)

关于约束命名的PS:直到本答案的上一版本,更详细的SQL示例包含CONSTRAINT <ConstraintName>用于为外键约束赋予唯一名称的子句.在@ypercube评论之后,我决定从示例中删除这些子句,原因有两个:命名约束是一个正交问题(即独立于)将约束放在适当的位置.将命名排除在外让我们可以专注于实际添加约束.

总之,为了命名约束,先于如任何提及PRIMARY KEY,REFERENCESFOREIGN KEYCONSTRAINT <ConstraintName>.我命名外键约束的方式是<TableName>_FK_<ColumnName>.我以相同的方式命名主键约束,仅PK作为前缀而不是FK.(自然和其他备用键将获得名称前缀AK.)


Mar*_*ith 9

您可以在一个操作中添加列和约束

ALTER TABLE dbo.Projects ADD 
            parentId INT NULL, 
            CONSTRAINT FK FOREIGN KEY(parentid) REFERENCES dbo.Projects
Run Code Online (Sandbox Code Playgroud)

您可以选择在引用的表名后面的括号中指定PK列,但这里不需要它.

  • +1,不知道在此上下文中可以省略引用的列名. (3认同)