当前位置: 首页 > 面试题库 >

如何防止自引用表变成圆形

公孙弘图
2023-03-14
问题内容

这是一个非常常见的问题,但我尚未找到我要寻找的确切问题和答案。

我有一个表,该表具有指向其自己的PK的FK,以启用任意深度的层次结构,例如经典的tblEmployee,它的列Manager是带有PK
tblEmployee.EmployeeID的FK。

假设在我的应用中,用户

  1. 创建新员工Alice和Dave,没有经理,因为他们是CEO和总裁。tblEmployee.Manager这两个记录的NULL也是如此。
  2. 创建新员工Bob,并以Alice为经理。然后以鲍勃(Bob)为经理创建查尔斯(Charles)。它们的Manager字段包含中另一个记录的主键值tblEmployee
  3. 编辑Alice的员工记录,这意味着指派Dave拥有她的经理(可以),但无意中将Alice的经理设置为Charles,比树中的Alice低两级。

现在,该表处于循环引用中,而不是适当的树中。

确保 不能 在应用程序中 完成 步骤3的 最佳 方法 是什么
?我只需要确保它会拒绝执行上一次SQL更新,而显示一些错误消息即可。

对于它是SQL Server中的html" target="_blank">数据库约束(必须在2008年或2012年工作)还是在C#应用程序的业务逻辑层中使用某种验证例程,我并不挑剔。


问题答案:

您可以CHECK CONSTRAINT通过验证管理员ID不是周期来执行此操作。检查约束中不能包含复杂的查询,但是如果首先将其包装在函数中,则可以:

create function CheckManagerCycle( @managerID int )
returns int
as
begin

    declare @cycleExists bit
    set @cycleExists = 0

    ;with cte as (
        select E.* from tblEmployee E where ID = @managerID
        union all
        select E.* from tblEmployee E join cte on cte.ManagerID = E.ID and E.ID <> @managerID
    )
    select @cycleExists = count(*) from cte E where E.ManagerID = @managerID

    return @cycleExists;

end

然后,您可以使用如下约束:

alter table tblEmployee
ADD CONSTRAINT chkManagerRecursive CHECK ( dbo.CheckManagerCycle(ManagerID) = 0 )

这将防止添加或更新记录以从任何来源创建循环

编辑:
一个重要的注意事项:检查约束在它们引用的列上得到验证。我最初将其编码为检查员工ID而不是经理ID的周期。但是,这不起作用,因为它仅在对ID列进行更改时触发。该版本之所以起作用,是因为它在ManagerID更改时会被触发。



 类似资料:
  • 我正在使用Bootstrap 3,并已将我的图像设置为像这样的圆形形状: 然而,这些图像更多的是椭圆形状(见截图)。我在基本引导CSS中没有看到任何我需要调整的东西。我看了几个关于这个主题的教程,没有一个提到任何额外的调整。此外,我已经编辑了图像的大小,但没有用。我做错了什么?

  • 问题内容: 如果使用此代码,则div的圆角不会剪切图像(结果是图像的方形角覆盖了div的圆角): 有谁知道如何获得一个圆形的div来防止子图像溢出? 问题答案: 这可能会或可能不会在您遇到的情况下起作用,但请考虑使图像成为CSS背景。在FF3中,以下工作正常: 我不确定还有另一种解决方法-如果您对图像本身应用边框(例如,较深),则会遇到同样的方形角问题。 编辑: 尽管在“为图像添加边框”情况下,图

  • 我序列化一个对象并将其保存为我的硬盘上的文件。当我阅读它时,只有在某些情况下它会抛出EofException。经过几个小时的调试,我无法找到一个问题。 下面是我的代码: 问题:我的序列化对象现在被破坏了,然后它现在是垃圾吗? 因为这个对象负责呈现用户保存的UI。如果用户登录,它应该呈现以前保存的UI状态。但是,对于某些用户,文件无法反序列化。

  • 问题内容: 我正在使用和自定义字体选择器。我希望显示所有可用的字体,每种字体名称以其自己的字体显示。我目前使用大约500种字体。 提供此功能的的示例: 问题在于,使用此渲染器时,在程序执行过程中,对象将变得无响应。第一次单击组合框以显示列表时,加载列表需要花费几秒钟的时间。第二次单击时,列表立即显示。 如果有人评论这一行 ,组合框就可以了。 如何防止这种反应迟钝? 问题答案: 发生的是,组合的内部

  • 下面是通常动态生成的内容。在页面的主要部分有一个< code > 为什么一个表可以变得比 宽?我一直认为,块元素采用其父元素的宽度? 表的相应 中的字符/空格数可能会有所不同。如何防止桌子长得比 div 宽?当然,我可以动态检查中的字符数,但是我如何处理这些信息? http://jsfiddle.net/vNnc6/ HTML:

  • 问题内容: 我有一个简单的hibernate查询,例如: 没什么花哨的,但是它在一个相当大的事务中被多次调用(持续一秒钟,可能会加载数十个或数百个实体)。Profiler显示很多时间花在: 换句话说-在运行实际查询之前刷新会更改。 我能以某种方式完全阻止Hibernate进行刷新吗? 如果没有,我该怎么做才能使其更快? 问题答案: 默认情况下,hibernate在会话期间发出查询之前刷新(Flus