2015-10-07 73 views
0

我創建了兩個表,部門和員工結構如下:刪除與部門經理外鍵約束僱員衝突

CREATE TABLE [dbo].[departments](
    [department_id] [bigint] IDENTITY(10,10) NOT NULL, 
    [department_name] [nvarchar](30) NOT NULL, 
    [manager_id] [bigint] NULL, 
    [location_id] [bigint] NULL, 
    [department_notes] [varchar](150) NULL, 
    [created_by] [bigint] NULL, 
    [created_date] [datetime] NULL, 
    [last_updated_by] [bigint] NULL, 
    [last_updated_date1] [datetime] NULL, 
    [status] [varchar](12) NOT NULL, 
CONSTRAINT [PK_departments] PRIMARY KEY CLUSTERED 
(
    [department_id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY], 
CONSTRAINT [UQ_NoRepeat] UNIQUE NONCLUSTERED 
(
    [department_name] ASC, 
    [location_id] ASC, 
    [status] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

SET ANSI_PADDING OFF 
GO 

ALTER TABLE [dbo].[departments] ADD CONSTRAINT [DF_departments_created_date] DEFAULT (getdate()) FOR [created_date] 
GO 

ALTER TABLE [dbo].[departments] ADD CONSTRAINT [DF_departments_created_date1] DEFAULT (getdate()) FOR [last_updated_date1] 
GO 

ALTER TABLE [dbo].[departments] ADD CONSTRAINT [DF_departments_status] DEFAULT ('Active') FOR [status] 
GO 

ALTER TABLE [dbo].[departments] WITH CHECK ADD FOREIGN KEY([manager_id]) 
REFERENCES [dbo].[employees] ([employee_id]) 
GO 

ALTER TABLE [dbo].[departments] WITH CHECK ADD CONSTRAINT [FK_departments_locations] FOREIGN KEY([location_id]) 
REFERENCES [dbo].[locations] ([location_id]) 
GO 

ALTER TABLE [dbo].[departments] CHECK CONSTRAINT [FK_departments_locations] 
GO 

ALTER TABLE [dbo].[departments] WITH CHECK ADD CONSTRAINT [Ck_deptStatus] CHECK (([Status]='Deleted' OR [Status]='Active')) 
GO 

ALTER TABLE [dbo].[departments] CHECK CONSTRAINT [Ck_deptStatus] 
GO 


CREATE TABLE [dbo].[employees](
    [employee_id] [bigint] NOT NULL, 
    [first_name] [nvarchar](20) NULL, 
    [last_name] [nvarchar](25) NOT NULL, 
    [email] [nvarchar](25) NOT NULL, 
    [phone_number] [nvarchar](20) NULL, 
    [hire_date] [date] NULL, 
    [job_id] [nvarchar](10) NOT NULL, 
    [salary] [numeric](8, 2) NOT NULL, 
    [commission_pct] [numeric](2, 2) NULL, 
    [manager_id] [bigint] NULL, 
    [department_id] [bigint] NOT NULL, 
    [allow_login] [bit] NOT NULL, 
    [user_id] [nvarchar](128) NULL, 
    [allow_email] [bit] NOT NULL, 
    [driv_lic_no] [nchar](20) NULL, 
    [reporting_to] [bigint] NULL, 
    [salutation] [nchar](10) NULL, 
    [date_of_birth] [date] NULL, 
    [gender] [nchar](10) NULL, 
    [blood_group] [nchar](10) NULL, 
    [Nationality] [nchar](10) NULL, 
    [gov_id] [nchar](25) NULL, 
    [passport_no] [nchar](25) NULL, 
    [passport_expir] [date] NULL, 
    [driv_lic_expir] [date] NULL, 
    [perm_address] [varchar](250) NULL, 
    [perm_city] [varchar](50) NULL, 
    [perm_state] [varchar](50) NULL, 
    [per_zip] [nchar](20) NULL, 
    [perm_country] [nvarchar](6) NULL, 
    [current_address] [varchar](250) NULL, 
    [current_city] [varchar](50) NULL, 
    [current_state] [varchar](50) NULL, 
    [current_zip] [nchar](20) NULL, 
    [current_country] [nvarchar](6) NULL, 
    [mobile_no] [nvarchar](20) NULL, 
    [notes] [varchar](250) NULL, 
    [added_by] [bigint] NULL, 
    [added_on] [date] NULL, 
    [send_cred_by_email] [bit] NOT NULL, 
    [user_name] [nvarchar](256) NULL, 
CONSTRAINT [PK_employees] PRIMARY KEY CLUSTERED 
(
    [employee_id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

SET ANSI_PADDING OFF 
GO 

ALTER TABLE [dbo].[employees] ADD CONSTRAINT [DF_employees_allow_login] DEFAULT ((0)) FOR [allow_login] 
GO 

ALTER TABLE [dbo].[employees] ADD CONSTRAINT [DF_employees_allow_email] DEFAULT ((0)) FOR [allow_email] 
GO 

ALTER TABLE [dbo].[employees] ADD DEFAULT ('Mr.') FOR [salutation] 
GO 

ALTER TABLE [dbo].[employees] ADD DEFAULT ((1)) FOR [send_cred_by_email] 
GO 

ALTER TABLE [dbo].[employees] WITH CHECK ADD CONSTRAINT [FK_employees_AspNetUsers] FOREIGN KEY([user_id]) 
REFERENCES [dbo].[AspNetUsers] ([Id]) 
GO 

ALTER TABLE [dbo].[employees] CHECK CONSTRAINT [FK_employees_AspNetUsers] 
GO 

ALTER TABLE [dbo].[employees] WITH CHECK ADD CONSTRAINT [FK_employees_countries] FOREIGN KEY([perm_country]) 
REFERENCES [dbo].[countries] ([country_id]) 
GO 

ALTER TABLE [dbo].[employees] CHECK CONSTRAINT [FK_employees_countries] 
GO 

ALTER TABLE [dbo].[employees] WITH CHECK ADD CONSTRAINT [FK_employees_countries1] FOREIGN KEY([current_country]) 
REFERENCES [dbo].[countries] ([country_id]) 
GO 

ALTER TABLE [dbo].[employees] CHECK CONSTRAINT [FK_employees_countries1] 
GO 

ALTER TABLE [dbo].[employees] WITH CHECK ADD CONSTRAINT [FK_employees_employees] FOREIGN KEY([employee_id]) 
REFERENCES [dbo].[employees] ([employee_id]) 
GO 

ALTER TABLE [dbo].[employees] CHECK CONSTRAINT [FK_employees_employees] 
GO 

有一些現有的員工,其已在部門表的經理,現在當我嘗試刪除任何這些經理僱員,我會得到一個外鍵約束衝突錯誤,阻止刪除語句。 請問有什麼問題?

+0

你能發佈確切的錯誤嗎? –

+0

沒有行被刪除。 嘗試刪除第4行時發生問題。錯誤源.Net SqIClient數據提供程序。錯誤消息DELETE語句與REFERENCE約束「FILdepartmen_manag_145C0A3F」衝突。衝突發生在數據庫「hr」,表「dbo.departments」,列imanager_idi中。該語句已終止。 更正錯誤並嘗試再次刪除該行或按ESC取消更改。 –

+0

問題是,如果部門表仍然有作爲部門經理的該員工的外鍵參考,則不能刪除員工。您需要首先切換到該部門的其他經理,或者在刪除該員工之前清空部門表中的外鍵。 –

回答

1

問題是你不允許這樣做。

外鍵約束是一個完整性約束,這意味着它確保跨表的數據完整性。

如果一個部門行說,僱員的ID,它是這個部門的經理是73,如果在數據庫中沒有員工提供的73

外國的ID它不會是好的鍵約束確保不會出現這種情況:

  1. 無法插入或更新一個部門行有不職員表中存在的經理ID
  2. 您不能刪除作爲一個經理引用僱員來自部門行
  3. 您不能更新被作爲一個管理者引用從一個部門行僱員的ID

的解決方案是首先修復由部門:通過更新部門

  1. 切換到不同的經理行調整經理
  2. NULL'ing出管理者的ID,說這個部門有沒有經理,如果允許

做任何這兩個後假設沒有其他外鍵引用,您應該可以刪除該員工。

+0

如果我希望表的工作方式如下: - 每個部門應該有0,1個經理 - 每當某個經理從員工表中移除時;該部門通過從部門表中刪除管理員標識成爲無管理員。 如何實施此方案? 感謝您的幫助 –

+0

您將使用'ON DELETE SET NULL'或類似的級聯操作,請參閱['CREATE TABLE']的語法(https://msdn.microsoft.com/zh-cn/library/ms174979.aspx )。 –

+0

非常感謝。它工作完美! –