2011-10-06 8 views
4

두 번째 테이블 인 Cars and Drivers는 세 번째 테이블 인 CarDrivers와 다 대다 관계로 결합되어 있습니다.여러 다 대다 관계 업데이트

내 UI를 사용하면 현재 자동차와 관련된 모든 드라이버를 확인할 수 있습니다. 각 검사는 행이 CarDrivers 테이블에 입력되어야 함을 나타냅니다.

제 질문은 : 사용자가 양식을 제출할 때 해당 행을 업데이트하는 가장 효율적인 방법은 무엇입니까?

체크 된 각 항목에 대해 CarDrivers에 행을 추가하고 변경하지 않은 항목을 남겨두고 체크하지 않은 각 항목에 대해 하나씩 삭제해야합니다.

내가 보는 유일한 방법은 각 조합을 한 번에 하나씩 살펴본 다음 이미 존재하지 않는 것을 추가하거나 제거해야하는 것을 제거하는 것입니다. 더 매끄러운 방법이 있습니까?

Entity Framework 4, ADO.NET, 스트레이트 SQL 쿼리 또는 저장 프로 시저를 사용할 수 있습니다.

답변

4

정확히 WHEN NOT MATCHED BY SOURCE 절을 처리하기 위해 MERGE 구문이 고안된 시나리오입니다.

대개 말하면 현재 상태 값을 준비 테이블에 넣고 MERGE을 사용하여 INSERTDELETE 작업을 한 번에 처리합니다.

여기에 간단한 스케치입니다 :

CREATE TABLE Cars (VIN INTEGER NOT NULL UNIQUE); 

CREATE TABLE Drivers (driver_licence_number INTEGER NOT NULL UNIQUE); 

CREATE TABLE CarDrivers 
(
VIN INTEGER NOT NULL REFERENCES Cars (VIN), 
driver_licence_number INTEGER NOT NULL 
    REFERENCES Drivers (driver_licence_number) 
); 

INSERT INTO Cars VALUES (1), (2), (3); 
INSERT INTO Drivers VALUES (22), (55), (99); 

INSERT INTO CarDrivers VALUES (1, 22), (1, 55); 

CREATE TABLE CarDrivers_staging 
(
VIN INTEGER NOT NULL REFERENCES Cars (VIN), 
driver_licence_number INTEGER NOT NULL 
    REFERENCES Drivers (driver_licence_number) 
); 

INSERT INTO CarDrivers_staging 
    VALUES (1, 55), -- remains 
      (1, 99); -- insert 
        -- DELETE (1, 22) 

MERGE INTO CarDrivers 
    USING CarDrivers_staging S 
     ON S.VIN = CarDrivers.VIN 
     AND S.driver_licence_number = CarDrivers.driver_licence_number 
WHEN NOT MATCHED THEN 
    INSERT (VIN, driver_licence_number) 
     VALUES (VIN, driver_licence_number) 
WHEN NOT MATCHED BY SOURCE THEN 
    DELETE; 
+0

감사합니다. 나는 그것을 나중에 이해할 수 있는지 알기 위해 오늘 나중에 나중에 시간을 보내야 할 것입니다. –

2

엄청난 양의 데이터가없는 경우이 방법이 더 효율적이지만 "더 매끄러운"것은 아닌지 의심 스럽습니다. 사용자가 자동차 - 운전자 관계를 업데이트하는 양식을 제출할 때 CarDrivers와 관련된 모든 관계를 먼저 삭제 한 다음 확인한 내용 만 삽입하는 것이 좋습니다. 또는 CarDrivers의 두 열에 uniq 제약 조건을 적용한 다음 코드에서 기존 레코드를 확인하는 대신 삽입 및 삭제에 대해 걱정할 수 있습니다.

+0

나는 모든 처음을 삭제 생각하지만 그건 나에게 끔찍하게 비효율적 인 것 같다. 고유 한 제한 조건으로 CarDrivers의 각 열이 고유하다는 것을 의미하면 둘 이상의 드라이버가 동일한 자동차에 연결되거나 하나 이상의 관리가 동일한 드라이버와 연결되는 것을 방지 할 수 있습니다. 그러나 결합 된 두 열이 고유하다는 것을 의미하면 그것이 내가 가진 방법입니다. 하지만 여전히 기존 기록을 확인해야합니다. 그렇지 않으면 앱에 데이터베이스 오류가 발생합니다. –

+0

오류가 롤백을 강제합니까? 그렇지 않으면 그 특별한 오류를 잡아 내고 따라갈 수 없었습니까? – imm

+1

나는 모든 데이터베이스 오류를 의미 할 수있는 일반 데이터베이스 예외를 얻을 것이라고 생각합니다. 일반적으로 예외를 발생시키지 않는 코드를 작성하고 싶습니다. –