如果我有一個表插入一個自我引用的表
Table
{
ID int primary key identity,
ParentID int not null foreign key references Table(ID)
}
一個人如何插入第一行到表?
從業務邏輯的角度來看,不應該刪除ParentID上的null約束。
如果我有一個表插入一個自我引用的表
Table
{
ID int primary key identity,
ParentID int not null foreign key references Table(ID)
}
一個人如何插入第一行到表?
從業務邏輯的角度來看,不應該刪除ParentID上的null約束。
在SQL Server中,一個簡單的插入會做:
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
結果
ID ParentID
----------- -----------
1 1
如果你想插入會從你的身份種子,插入不同的值將失敗。
UPDATE:
的問題不是上下文是什麼太明確的(即是應該在實時生產系統,或只是一個DB安裝腳本工作的代碼),並從意見似乎很難編碼該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'))
然後人們可以照常查詢最後的身份(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
結果:
ID ParentID
----------- -----------
1 1
2 2
3 3
currentIdentity
---------------------------------------
3
currentIdentity
---------------------------------------
4
ID ParentID
----------- -----------
1 1
2 2
3 3
5 5
如果你需要使用一個明確的數值爲第一ID時,您插入第一條記錄,則可以禁用IDENTITY值的檢查(請參閱:MSDN: SET IDENTITY_INSERT (Transact-SQL))。
下面是illistrates這樣一個例子:
CREATE TABLE MyTable
(
ID int PRIMARY KEY IDENTITY(1, 1),
ParentID int NOT NULL,
CONSTRAINT MyTable_ID FOREIGN KEY (ParentID) REFERENCES MyTable(ID)
);
SET IDENTITY_INSERT MyTable ON;
INSERT INTO MyTable (ID, ParentID)
VALUES (1, 1);
SET IDENTITY_INSERT MyTable OFF;
WHILE @@IDENTITY <= 5
BEGIN
INSERT INTO MyTable (ParentID)
VALUES (@@IDENTITY);
END;
SELECT *
FROM MyTable;
IF OBJECT_ID('MyTable') IS NOT NULL
DROP TABLE MyTable;
這似乎是NOT NULL
約束是不適合的樹的根節點如此。它根本沒有父母。所以假設ParentID
是NOT NULL
從一開始就被打破了。
我建議你把它可空和ParentID
添加一個索引來驗證有隻有一個值NULL
:
create unique nonclustered index ... on T (ParentID) where (ParentID IS NULL)
這是很難執行SQL Server中的聲音樹形結構。您可以在圖表中獲得多個根或循環。很難驗證所有這一切,並且不清楚是否值得努力。根據具體情況,這可能是好的。
Intersting問題。是否有可能引用自己?如果它是新創建的,你甚至可以創建1條記錄? – YvesR
你的第一排的父母是哪一行? –
對於第一行ParentID應該是ID。如果我想在我的樹結構中使用多個根,那麼任何根都有ParentID == ID。因此,問題可以擴展爲 - 如何插入根行?存儲過程可以使用SCOPE_IDENTITY來進行插入嗎? – Nezreli