Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
sql检查两列中的逻辑错误_Sql_Sql Server_Sql Server 2008_Database Design_Data Modeling - Fatal编程技术网

sql检查两列中的逻辑错误

sql检查两列中的逻辑错误,sql,sql-server,sql-server-2008,database-design,data-modeling,Sql,Sql Server,Sql Server 2008,Database Design,Data Modeling,假设我有一个只包含两列的employee表: 雇员身份证 经理id 添加到此表中的所有员工都会有一个随行的经理id,这实际上是一个已经存在的员工id,除了一个,CEO可能没有经理,但这并不重要 如果A是B的管理者,我们如何执行检查,使A的管理者可以接受除B以外的任何值,因此导致违反业务规则?我认为最好的方法是在表中的insert上创建一个触发器,只需检查经理id是否不在SELECT employee id from employee中,其中经理id=%insertid%。问题更严重,您希望避免图

假设我有一个只包含两列的employee表:

雇员身份证 经理id 添加到此表中的所有员工都会有一个随行的经理id,这实际上是一个已经存在的员工id,除了一个,CEO可能没有经理,但这并不重要


如果A是B的管理者,我们如何执行检查,使A的管理者可以接受除B以外的任何值,因此导致违反业务规则?

我认为最好的方法是在表中的insert上创建一个触发器,只需检查经理id是否不在SELECT employee id from employee中,其中经理id=%insertid%。

问题更严重,您希望避免图形中的任何循环,让它变成一棵树

我认为您最好在应用程序级别这样做

更新:但是如果你更喜欢用触发器,看看。您可以在检查周期的触发器中创建递归查询:

create trigger prevent_management_cycles on employee
instead of update
as

declare @found_rows int

;with cycle_detector (employee_id) as (
  select employee_id from inserted
  union all
  select employee.employee_id from employee
  join cycle_detector 
  on employee.manager_id = cycle_detector.employee_id
) 
select @found_rows = count(*)
from cycle_detector
join inserted 
on inserted.manager_id = cycle_detector.employee_id

if @found_rows > 0
  raiserror('cycle detected!', 1, 1)
else
  -- carry on original update
  update employee 
    set employee.manager_id = inserted.manager_id
    -- other columns...
  from employee 
  join inserted on employee.employee_id = inserted.employee_id

注意:假设employee\u id是主键,manager\u id是指向employee.employee\u id的外键。

答案的一半是外键:manager\u id引用employeeemployee\u id


另一半是检查约束,manager\u ideemployee\u id

您想在插入过程中检查条件,还是对表本身施加限制?您不是在最后一段中弄混了吗?您使用的是MySQL、SQL Server还是Oracle?或者你真的在为所有三个平台寻找编码解决方案吗?Balanivash:在插入过程中检查条件会很好enough@Aaron伯特兰:我用的是SQLServer2008。任何一种语言的解决方案都可以。我只需要知道它是如何在数据库级别完成的。哦,对了,这不能保证树的事情。为此,特别是如果您打算对子层次结构执行操作,请查看嵌套集模型:检查约束将无法提供此功能-触发器是唯一一个可以轻松处理此问题的选项。是的,它可以。但我通常更喜欢将这种业务逻辑与应用程序的持久性机制分离。这样更容易维护、测试和发展。数据库构建基于业务实体及其规则。它也是集中式的,同样易于维护,并且比除最简单的应用程序之外的所有应用程序都能更好地扩展负载。坦率地说,使用数据库作为哑存储完全是浪费…尽可能少的触发器。否则-主要是表和外键。通过存储过程进行操作是我的首选,因为ORM在复杂的查询中受到影响,而应用层的SQL更需要测试。和强制参数化…@jaane:没有要求SO答案提供一个完整的功能性答案-这只符合我们的最佳利益。我相信你自己是有能力的,但你可以请保罗澄清一下……触发器并不能解决问题。它只检查自我循环。@Downvoter:如果你因为期待一个功能齐全的答案而放弃投票,或者是因为报复别人的放弃投票-也许是时候长大了?我在接受答案之前尝试过向上投票,但它只是注册用户而已。。。公认的答案是。。。。插入式触发器不需要检查这一点。由于该员工是全新的,任何其他员工都可以成为他的经理-1,这不是因为我期待一个功能齐全的答案,而是至少一个指向正确方向的答案。。。