我正在创建sql hirercky表
这是我的代码;
约束功能代码
alter Function Accounts.Types_Sub_Check_fn (@ID uniqueidentifier, @Sub Uniqueidentifier) returns int
begin
--declare @id uniqueidentifier = '8c7d4151-246c-476c-adf6-964ca9afdd3c' declare @sub uniqueidentifier = '47c2b6da-25fc-4921-adfa-b1f635bddde6'
declare @a int
declare @b int =(iif(@ID=@SUB,2,0))
;with cte(id, lvl) as
(
select f.sub,
1
from Accounts.Types as f
where f.id = @id
union all
select f.sub,
lvl + 1
from Accounts.Types as f
inner join cte as c
on f.id = c.id
)
select @a = (select count (*)
from cte
where id =@sub) + @b
option (maxrecursion 0)
return @a
end
go
表格代码
create Table Accounts.Types
(
ID uniqueidentifier not null CONSTRAINT DF_Accounts_Types_ID DEFAULT newid() CONSTRAINT PK_Accounts_Types_ID PRIMARY KEY NONCLUSTERED (ID) ,
Name varchar(200) not null CONSTRAINT UQ_Accounts_Types_NAME UNIQUE (NAME),
Sub uniqueidentifier CONSTRAINT FK_Accounts_Types_Sub Foreign key references Accounts.Types ,
Ctype uniqueidentifier CONSTRAINT FK_Accounts_Types_Ctype Foreign key references Accounts.Types ,
insert_time datetime not null CONSTRAINT DF_Accounts_Types_Insert_Time DEFAULT getdate() ,
insert_user uniqueidentifier CONSTRAINT DF_Accounts_Types_Insert_User DEFAULT'9EC66F53-9233-4A6C-8933-F8417D2BB5A9' ,
ts timestamp,
INDEX IX_Accounts_Types_NAME#ASC CLUSTERED (Name ASC),
Constraint Check_Accounts_Types_Sub check (Accounts.Types_Sub_Check_fn(ID,Sub)<=1)
)
go
如果尝试将itseft作为父项(在子列中)
插入,则此函数将给出2如果它已经是一个孩子,它会给1,它试图作为其父
插入创建Check约束以检查任何id的父(子列)是否不应该是其子或子, 并且它本身不能是它的父母
当我尝试插入与检查约束不匹配的数据时,它会卡住,并发出超时错误,
例如:
insert into Accounts.Types (ID, Name, Sub)
values ('607936b9-6f95-4989-8ebe-87a08807f43e','LLL','607936b9-6f95-4989-8ebe-87a08807f43e')
这会给出超时
任何人都可以帮助我,我需要摆脱时间错误;仅获取约束错误答案 0 :(得分:1)
简单的问题 - 当您的ID和Sub是相同的值并且您不限制maxrecursion或lvl时,您的递归何时结束?决不。它永远不会结束。
if (($date >= $snowStart) && ($date <= $snowEnd))
{
// do this and that
}
您必须删除ID = Sub的行或添加maxrecursion或添加级别限制或规范化表格。
答案 1 :(得分:0)
alter Function Accounts.Types_Sub_Check_fn (@ID uniqueidentifier, @Sub Uniqueidentifier) returns int
begin
--declare @id uniqueidentifier = '00279c6b-df00-4144-810d-571fdb1c5109' declare @sub uniqueidentifier = 'bc887e7b-36d2-4ece-8ec1-720dc81a9de4'
declare @a int = 0
declare @b int =(iif(@ID=@SUB,2,0))
if @ID <> @sub
begin
;with cte(id, lvl) as
(
select f.Sub ,
1
from Accounts.Types as f
where f.id = @sub
union all
select iif(f.Sub = @sub, Null, f.sub),
lvl + 1
from Accounts.Types as f
inner join cte as c
on f.id = c.id
)
select @a = (select count (*)
from cte
where id =@id)
option (maxrecursion 0);
end
-- select @a + @b
return @a + @b
end
go