Проверка SQL на логические ошибки в 2 столбцах - PullRequest
4 голосов
/ 05 июля 2011

Если у меня есть таблица employee только с 2 столбцами:

  • employee_id
  • manager_id

Все сотрудники, добавленные в эту таблицу, будут иметьсопровождающий manager_id, который на самом деле employee_id, который уже существует (за исключением одного, у генерального директора, вероятно, нет менеджера, но это не важно).

Если A является менеджеромB, как мы осуществляем проверку таким образом, чтобы менеджер А мог принять любое значение, НО B, что привело бы к нарушению бизнес-правила?

Ответы [ 3 ]

0 голосов
/ 05 июля 2011

Проблема еще глубже, вам нужно избегать любых циклов в вашем графике , что делает его деревом .

Я думаю, вам лучше делать это на уровне приложений.

ОБНОВЛЕНИЕ: Но если вы предпочитаете делать это с помощью триггера, взгляните на общие табличные выражения (CTE) . Вы можете создать рекурсивный запрос в триггере, который проверяет циклы:

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_id является первичным ключом, а manager_id является внешним ключом, указывающим обратно на employee.employee_id.

0 голосов
/ 05 июля 2011

Половина ответа - внешний ключ: manager_id ссылается на employee (employee_id)

Другая половина - проверочное ограничение, manager_id <> employee_id

0 голосов
/ 05 июля 2011

Я бы сказал, что наилучшим способом было бы создать триггер на вставке в таблицу, который бы просто проверял, что manager_id NOT IN (SELECT employee_id from employee where manager_id = %insertid%).

...