SQL:自引用行

时间:2017-01-13 09:53:44

标签: sql sql-server tsql foreign-keys

我有一个Users表:

Create table dbo.Users (
    Id int IDENTITY (1, 1) PRIMARY KEY,
    ManagerId int FOREIGN KEY references dbo.Users(Id)
);

用户有经理。

经理本身就是用户。

是否可以拥有ManagerId NOT NULL并插入一行告诉SQL它自己引用?即ManagerID = Id

PS:我已经知道我可以使用ManagerID NULL分两步完成,我也知道我可以编写我的应用程序,以便NULL表示用户正在管理自己,但这不是重点我的问题。

1 个答案:

答案 0 :(得分:1)

有了标识栏,我不这么认为。但是我们已经有了很长时间的序列。你可以像这样定义你的表:

create sequence [SQ_Users] as int start with 1;

create table dbo.Users (
    Id int NOT NULL 
        constraint [PK_Users] PRIMARY KEY
        constraint [DF_UserID] DEFAULT (next value for [dbo].[SQ_Users]),
    ManagerId int not null
        constraint [FK_User_Manager] FOREIGN KEY references dbo.Users(Id)
);

(注意:我命名了你的约束因为我不喜欢系统命名的那些;它是我提供的服务)。现在,如果你想让一个用户成为他们自己的经理,你可以这样做:

declare @UserId int = next value for [dbo].[SQ_Users];
insert into dbo.Users (ID, ManagerID) values (@UserID, @UserID);

请注意,这并没有消除表本身的常见用例自动生成自己的ID。也就是说,你仍然可以这样做:

insert into dbo.Users (ManagerID) values (@ManagerID);

对于它的价值,它是分层数据中的常见习语(就像你所拥有的那样),父ID的NULL值意味着元素位于顶部或引用自身。也就是说,你当前的设置不应该引起“下一个人”的任何侧面扫视。