如果我有一张桌子
Table
{
ID int primary key identity,
ParentID int not null foreign key references Table(ID)
}
Run Code Online (Sandbox Code Playgroud)
如何将第一行插入表中?
从业务逻辑的角度来看,不应该删除ParentID上的空约束.
在SQL Server中,一个简单的INSERT将执行:
create table dbo.Foo
(
ID int primary key identity,
ParentID int not null foreign key references foo(ID)
)
go
insert dbo.Foo (parentId) values (1)
select * from dbo.Foo
Run Code Online (Sandbox Code Playgroud)
结果是
ID ParentID
----------- -----------
1 1
Run Code Online (Sandbox Code Playgroud)
如果您尝试插入的值与您的标识种子不同,则插入将失败.
更新:
关于上下文是什么(即代码应该在实时生产系统中工作还是仅仅是数据库设置脚本)的问题并不是很清楚,而且从注释中看起来很难编码ID可能不是一个选项.虽然上面的代码通常可以在数据库初始化脚本中正常工作,其中层次结构根ID可能需要知道并且是常量,但对于林(具有预先未知的ID的多个根),以下代码应按预期工作:
create table dbo.Foo
(
ID int primary key identity,
ParentID int not null foreign key references foo(ID)
)
go
insert dbo.Foo (parentId) values (IDENT_CURRENT('dbo.Foo'))
Run Code Online (Sandbox Code Playgroud)
然后可以像往常一样查询最后一个身份(SCOPE_IDENTITY等等).为了解决@ usr的问题,代码实际上是事务安全的,如下例所示:
insert dbo.Foo (parentId) values (IDENT_CURRENT('dbo.Foo'))
insert dbo.Foo (parentId) values (IDENT_CURRENT('dbo.Foo'))
insert dbo.Foo (parentId) values (IDENT_CURRENT('dbo.Foo'))
select * from dbo.Foo
select IDENT_CURRENT('dbo.Foo')
begin transaction
insert dbo.Foo (parentId) values (IDENT_CURRENT('dbo.Foo'))
rollback
select IDENT_CURRENT('dbo.Foo')
insert dbo.Foo (parentId) values (IDENT_CURRENT('dbo.Foo'))
select * from dbo.Foo
Run Code Online (Sandbox Code Playgroud)
结果:
ID ParentID
----------- -----------
1 1
2 2
3 3
currentIdentity
---------------------------------------
3
currentIdentity
---------------------------------------
4
ID ParentID
----------- -----------
1 1
2 2
3 3
5 5
Run Code Online (Sandbox Code Playgroud)