Say I have a table named EMPLOYEE, and the table has a field called ManagerID. This field is a FK to another record of the 开发者_开发知识库EMPLOYEE table of who their manager is. What is an ideal way to verify that there is no circular reference (recursive foreign keys)?
EDIT - Let me add that every employee does NOT need a manager. There will be some employee records that do not have their ManagerID field set.
*Example: User 123 has User 345 as their manager. User 345 has User 567 as their manager. For some crazy reason, User 567 has User 123 as their manager.
I want to check if User 345 is in a circular reference.*
What is the best way to figure this out? A simple query? Business logic code (C#/VB.NET)?
What have other people done?
Example table schema -
-- Employee Table --
UserID (int - PK)
ManagerID (int - FK to another UserID; can be null)
Here's a few starters - they either use recursive CTEs or cursors:
http://blogs.msdn.com/b/sqlazure/archive/2010/07/01/10033575.aspx
http://social.msdn.microsoft.com/Forums/en-ZA/transactsql/thread/50a0bd26-87c8-4197-84f9-5fb1dfd792b6
If you are dealing with SQL server, here is the solution that matches your requirement; You need to write CTE to find cyclic references;
Below query will give you user IDs having cyclic reference
WITH TRACKER AS
(
SELECT U.id,U.manager_id,CAST(','+cast(U.id as varchar(36))+',' as varchar(max)) as Path,0 as Cycle FROM User_table AS U
UNION ALL
SELECT U.id,U.manager_id, TRACKER.Path + CAST(U.id AS varchar(36))+',', case WHEN TRACKER.Path LIKE '%,'+CAST(U.id AS VARCHAR(36)) + ',%' then 1 else 0 end FROM User_table AS U
INNER JOIN TRACKER ON U.manager_id = TRACKER.id WHERE TRACKER.Cycle=0
)
SELECT TRACKER.id from TRACKER where Cycle= 1;
精彩评论