2017-11-04 1 views
0

I는 다음과 같은 테이블이 때 삭제 FK
층계
설명캐스케이드 결합 열 값이 고유 외래 키

,

[객실] FK
설명

[특징]
아이디 PK
표제

[object_features]
아이디 PK
가 FEATUREID FK floorid FK
locationid

아이디 PK
objectid FK ((위치 값, 1 = 값, 3 = 값)

이제 위치 X가 삭제되면 [위치] .id, [바닥] .id 또는 [객실] .id에 연결됩니다. [locations] 관련 방과 바닥을 삭제하고 싶습니다. (예 방은 장소가 아닌 바닥에 직접 연결될 수 있습니다.) 캐스케이드 삭제로 쉽게 완료됩니다.

그러나 다른 오브젝트 타입 (위치, 층 및 룸)의 각각은 또한 [object_features] .objectid 및 [object_features] .objecttype가있을 수 있다는 것을 의미 [object_features]에 저장되어 0 이상의 특징을 가질 수있다 동일한 값을 두 번 이상 사용하지만 [object_features] .featureid와 결합 할 때 고유 한 조합입니다.

위치를 삭제할 때 해당 위치 X 삭제로 인해 [위치], [층] 및/또는 [회의실]에서 삭제 된 행과 관련된 [object_features]의 모든 행을 삭제하려고합니다. 행을 삭제할 때 작업을 수행하는 각 테이블 ([locations], [floor], [rooms])에 논리를 추가해야한다고 생각합니다. 트리거가 트릭을 수행 할 수있는 것처럼 느껴지지만 이것이 권장 접근 방법인지 확실하지 않습니다. 또한이를 구현하는 방법을 잘 모르겠습니다.

이미 여기에서 확인 : CASCADE DELETE on two foreign key constraints,하지만 다른 해결책 인 것 같습니다.

INSTEAD OF DELETE 트리거가이 DRI 여러 업데이트 경로로 인해 허용되지 않는 경우에는 삭제 캐스케이드 수행하기 위해 SQL 서버에서 사용할 수 있습니다

CREATE TABLE [dbo].[locations](
    [id] [int] IDENTITY(1,1) NOT NULL, 
    [title] [nvarchar](500) NOT NULL, 
CONSTRAINT [PK_homes] PRIMARY KEY NONCLUSTERED 
(
    [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] TEXTIMAGE_ON [PRIMARY] 
GO 



CREATE TABLE [dbo].[location_floors](
    [id] [int] IDENTITY(1,1) NOT NULL, 
    [locationid] [int] NOT NULL, 
CONSTRAINT [PK_location_floors] PRIMARY KEY CLUSTERED 
(
    [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 

ALTER TABLE [dbo].[location_floors] WITH CHECK ADD CONSTRAINT [FK_location_floors_locations] FOREIGN KEY([locationid]) 
REFERENCES [dbo].[locations] ([id]) 
ON DELETE CASCADE 
GO 

ALTER TABLE [dbo].[location_floors] CHECK CONSTRAINT [FK_location_floors_locations] 
GO 


CREATE TABLE [dbo].[location_rooms](
    [id] [int] IDENTITY(1,1) NOT NULL, 
    [locationid] [int] NOT NULL, 
    [floorid] [int] NULL, 
CONSTRAINT [PK_location_rooms] PRIMARY KEY CLUSTERED 
(
    [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 

ALTER TABLE [dbo].[location_rooms] WITH CHECK ADD CONSTRAINT [FK_location_rooms_locations] FOREIGN KEY([locationid]) 
REFERENCES [dbo].[locations] ([id]) 
ON DELETE CASCADE 
GO 

ALTER TABLE [dbo].[location_rooms] CHECK CONSTRAINT [FK_location_rooms_locations] 
GO 


CREATE TABLE [dbo].[features](
    [id] [int] IDENTITY(1,1) NOT NULL, 
    [title] [nvarchar](50) NOT NULL, 
    [createdate] [datetime] NOT NULL, 
CONSTRAINT [PK_voorzieningen] PRIMARY KEY CLUSTERED 
(
    [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 

ALTER TABLE [dbo].[features] ADD CONSTRAINT [DF_voorzieningen_createdate] DEFAULT (getdate()) FOR [createdate] 
GO 


CREATE TABLE [dbo].[object_features](
    [id] [int] IDENTITY(1,1) NOT NULL, 
    [objectid] [int] NOT NULL, 
    [objecttype] [tinyint] NOT NULL, 
    [featureid] [int] NOT NULL, 
    [createdate] [datetime] NOT NULL, 
CONSTRAINT [PK_location_voorzieningen] PRIMARY KEY CLUSTERED 
(
    [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 

ALTER TABLE [dbo].[object_features] ADD CONSTRAINT [DF_location_voorzieningen_createdate] DEFAULT (getdate()) FOR [createdate] 
GO 

ALTER TABLE [dbo].[object_features] WITH CHECK ADD CONSTRAINT [FK_object_features_features] FOREIGN KEY([featureid]) 
REFERENCES [dbo].[features] ([id]) 
ON DELETE CASCADE 
GO 

ALTER TABLE [dbo].[object_features] CHECK CONSTRAINT [FK_object_features_features] 
GO 

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'1=location, 2=floor, 3=room' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'object_features', @level2type=N'COLUMN',@level2name=N'objecttype' 
GO 

답변

0

DDL.

다음은 적절한 순서로 필요한 삭제 작업을 수행하는 예입니다. 계단식 삭제가 필요한 다른 테이블의 트리거에 대해서도 비슷한 패턴을 따르십시오.

CREATE TRIGGER tr_location_delete 
ON dbo.locations 
INSTEAD OF DELETE 
AS 
SET NOCOUNT ON; 

--delete rooms for location 
DELETE rooms 
FROM dbo.rooms 
JOIN dbo.floors ON floors.id = rooms.floorid 
JOIN deleted ON deleted.id = rooms.floorid; 

--delete floors for location 
DELETE floors 
FROM dbo.floors 
JOIN deleted ON deleted.id = floors.locationid; 

--delete location 
DELETE locations 
FROM dbo.locations 
JOIN deleted ON deleted.id = locations.id; 
GO 
+0

나는 이미 해당 locationid와 관련된 객실과 층을 삭제하기 위해 locationid를 사용하는 계단식 삭제 규칙을 구성했습니다.귀하의 코드에서 알 수 있듯이, 이미 설정 한 기본 캐스케이드 삭제를 무시하고 있습니다. 맞습니까? 그러나 내가 직면하는 문제는 삭제되는 행 (위치, 층 또는 실)이 어떤 테이블에서 [object_features]의 관련 행을 삭제하는지에 따라이를 확인하는 방법입니다. 나는 아직도 어떻게하는지 확신 할 수 없다. 도울 수 있니? – Flo

+0

이 트리거의 목적은 DRI를 통해 삭제하는 대신 삭제 캐스케이드를 수행하는 것입니다. 나는 다중 경로를 야기 할 수있는 텍스트 설명에 지정된대로 연쇄 외래 키를 만들 수 있다고 생각하지 않습니다. 명확한 질문에 제약 조건이있는 실제 CREATE TABLE DDL을 추가하십시오. –

+0

DDL을 추가했습니다. 너무 복잡하다면, 아마도 objecttype 당 object_features를위한 별도의 테이블을 생성해야합니까? 그래서 object_features_locations, object_features_floors 및 object_features_rooms .... 아마도 이것이 최선의 방법일까요? – Flo

관련 문제