【发布时间】:2016-12-02 14:37:17
【问题描述】:
我正在创建 sqlhirercky 表
这是我的代码;
约束函数代码
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
如果尝试将其插入作为父级(在子列中),此函数将给出 2 作为结果
如果它已经是一个孩子,它会给出 1,它试图作为它的父母插入
创建 Check 约束是为了检查任何 id 的父(子列)是否不应该是它的子或孙子, 并且它本身不能是它的父级
当我尝试插入与检查约束不匹配的数据时,它卡住了,并给出了超时错误,
例如:
insert into Accounts.Types (ID, Name, Sub)
values ('607936b9-6f95-4989-8ebe-87a08807f43e','LLL','607936b9-6f95-4989-8ebe-87a08807f43e')
这会超时
谁能帮帮我,我需要摆脱超时错误;只得到约束错误
【问题讨论】:
-
看起来您正在通过构建 CSV 字符串然后对其执行 LIKE 来检查父/子/自我关系。您可能可以直接使用递归 CTE 检查关系,而无需构建 CSV 字符串。
-
您是否排除了通过
hierarchyid数据类型使用构建来支持建模层次结构? -
如果在“树”中创建循环,则 CTE 将运行一段时间。 This 答案显示了一种在检测到循环时终止递归的方法。
标签: sql-server tsql