Sql 表的自引用

Sql 表的自引用,sql,sql-server,self-join,Sql,Sql Server,Self Join,我是SQL Server的新手 我想引用与下面相同的表列 CREATE TABLE JOIN_DEPARTMENTS ( DEPTID INT PRIMARY KEY, DEPTNAME VARCHAR(20) ); CREATE TABLE JOIN_EMPLOYEES ( EMPID INT PRIMARY KEY, EMPNAME VARCHAR(20), MGRID INT, DEPTID INT FOREIGN KEY REFERENCES JOIN_DEPA

我是SQL Server的新手

我想引用与下面相同的表列

CREATE TABLE JOIN_DEPARTMENTS
(
  DEPTID INT PRIMARY KEY,
  DEPTNAME VARCHAR(20)
);

CREATE TABLE JOIN_EMPLOYEES
(
  EMPID INT PRIMARY KEY,
  EMPNAME VARCHAR(20),
  MGRID INT,
  DEPTID INT FOREIGN KEY REFERENCES JOIN_DEPARTMENTS(DEPTID),
  CONSTRAINT FK_SELFREFE FOREIGN KEY (MGRID) REFERENCES EMPLOYEES(EMPID) ON DELETE SET NULL
);

INSERT INTO JOIN_DEPARTMENTS VALUES (100, 'BFS');
INSERT INTO JOIN_DEPARTMENTS VALUES (101, 'MELT');

INSERT INTO JOIN_EMPLOYEES VALUES(1, 'SARA', NULL, 100);  --> inserts fine
INSERT INTO JOIN_EMPLOYEES VALUES(2, 'SANTHOSH', 1, 100); --> 
抛出以下错误

味精547,第16级,状态0,第530行
INSERT语句与外键约束“FK_SELFREFE”冲突。冲突发生在数据库“SARA”、表“dbo.EMPLOYEES”、列“EMPID”中


这里我做错了什么?

您的约束引用了员工,但您正在将其插入到“加入员工”中-检查员工以确保EMPID=1存在,或者修改约束以检查“加入员工”而不是“员工”

编辑:回应评论:我不知道如何使DELETE SET NULL约束上的自引用起作用,但我认为您可以通过创建一个AFTER DELETE触发器来实现相同的目标,该触发器在已删除行的MGRID=EMPID的所有行中将MGRID设置为NULL。我不能完全测试这一点,但我认为这会起作用

CREATE TRIGGER trJOIN_EMPLOYEE_AfterDel   ON  JOIN_EMPLOYEES   AFTER DELETE
AS BEGIN
    SET NOCOUNT ON;
    UPDATE JOIN_EMPLOYEES SET MGRID = NULL
    WHERE MGRID IN (SELECT EMPID FROM deleted)
END
基本上,它所做的是在处理删除之后,但在事务被视为完成之前,它会返回并将引用最近删除的员工ID的任何MGRIDs设置为NULL

请注意,Microsoft有一些相关信息

说“由单个删除或更新触发的一系列级联引用操作必须形成一个不包含循环引用的树。”所以我认为您不会让自引用约束起作用


另外请注意,在允许您创建触发器之前,您可能必须删除部分或全部约束,我认为这只是因为没有删除触发器而导致冲突,但删除触发器后有可能会与某些约束冲突-同样,我没有足够的经验来确定,试试看。

你是对的。我删除了表并再次创建了它,它开始出现以下错误。在这种情况下,我们不能使用“ON Delete”吗?Msg 1785,第16级,状态0,第512行在表“JOIN_EMPLOYEES”上引入外键约束“FK_SELFREFE”,可能导致循环或多个级联路径。指定“在删除时不执行操作”或“在更新时不执行操作”,或修改其他外键约束。Msg 1750,级别16,状态0,第512行无法创建约束或索引。看到以前的错误。很抱歉,我不知道那个错误的答案,这不是我以前遇到过的情况:-(@SaravanaSanthosh这是你问的问题的答案。我想你应该接受它。对于新的错误,也许你应该准备新的问题?