FireDAC의 TFDDataSet.MergeDataSet 메소드를 이용해 구조가 같은(또는 확장된) 데이터셋을 병합해 하나의 데이터셋을 구성할 수 있습니다.
제가 테스트한 목적은,
데이터스냅으로 데이터량이 많은 데이터 중 일부분 데이터만 가져오고, 필요한 경우 추가로 가져와 병합(페이징 기능 구현) 할 목적으로 테스트 진행해 봤습니다.
TFDDataSet.MergeDataSet
procedure MergeDataSet(ASource: TFDDataSet; AData: TFDMergeDataMode = dmDataMerge; AMeta: TFDMergeMetaMode = mmNone);
TFDMergeDataMode
데이터셋 데이터를 병합하는 방법 지정
모드 | 설명 | 데이터셋 변경 사항 커밋 |
---|---|---|
dmNone | 데이터를 병합하지 않습니다. | - |
dmDataSet | 원 데이터셋 클리어 후 지정된 데이터셋의 레코드를 대신 삽입합니다. | 예 |
dmDataAppend | 지정된 데이터셋의 레코드를 원 데이터셋에 덧붙입니다. | 예 |
dmDataMerge | 지정된 데이터셋의 레코드의 기본 키를 취득하고 그것과 같은 기본 키 대응 레코드를 원 데이터셋에서 찾습니다. 그 후 다음 중 하나를 수행합니다.
| 예 |
dmDeltaSet | 원 데이터셋을 지우고 지정된 데이터셋의 레코드를 대신 삽입합니다. | 아니오 |
dmDeltaAppend | 지정된 데이터셋의 레코드를 원 데이터셋에 덧붙입니다. | 아니오 |
dmDeltaMerge | 지정된 데이터셋의 레코드의 기본 키를 취득하고 그것과 같은 기본 키 대응 레코드를 원 데이터셋에서 찾습니다. 그 후 다음 중 하나를 수행합니다.
| 아니오 |
TFDMergeMetaMode
데이터셋 메타데이터 병합하는 방법 지정
모드 | 설명 |
---|---|
mmNone | 메타 데이터의 비교 및 병합을하지 않습니다. |
mmMerge | 지정된 데이터 집합에서 열 이름을 검색하여 이름이 같은 열이 데이터셋에서 찾습니다. 그 후 다음 중 하나를 수행합니다.
|
mmAdd | 지정된 데이터 집합에서 열 이름을 검색하여 이름이 같은 열이 데이터셋에서 찾습니다. 같은 이름의 열이 데이터셋에서 찾을 수없는 경우 새 열을 데이터셋에 추가합니다. |
mmUpdate | 지정된 데이터 집합에서 열 이름을 검색하여 이름이 같은 열이 데이터셋에서 찾습니다. 같은 이름의 열이 데이터셋에서 발견 된 경우 해당 열의 데이터 형식과 크기를 지정된 데이터셋의 메타 데이터로 업데이트합니다. |
mmAddOrError | 이 데이터셋의 메타 데이터를 다음과 같이 업데이트합니다.
|
mmError | 지정된 데이터 집합에서 열 이름을 검색하여 이름이 같은 열이 데이터셋에서 찾습니다. 동명의 열이 없거나, 동명의 열 데이터 형식이나 크기가 일치하지 않는 경우는 예외를 전달합니다. |
TFDDataSet.MergeDataSet 데모
해당 데모는 왼쪽에 표시되는 3개 데이터셋(memList, memList2, memDetail)을 병합해 오른쪽에 표시되는 데이터셋(memMerge)으로 병합합니다.
병합할 대상 데이터는 같은 구조(ID, Name)의 데이터셋 2개와 확장된 구조(ID, Name, addr)를 데이터셋을 병합합니다.
작성하며 주의할 점은,
- 병합해 넣을 데이터셋(memMerge)에 기본키가 설정되어 있어야 합니다. => 아래 코드에서 "memMerge.Table.PrimaryKey := memDetail.Table.PrimaryKey;"
- 필드 종류가 다른 데이터셋(memDetail)을 병합할 경우, 병합할 데이터셋(memMerge)에 데이터가 있을 경우 메타데이터를 변경할 경우(mmMerge) 코드 내부에서 데이터셋 메타데이터(필드 정보)를 재 생성 함. 이때 기본키가 설정되지 않아 위 1번 오류 발생 -> 미리 필드를 생성 후 mmMerge 호출하지 말 것(필드 종류가 다를 경우에 한함)
procedure TForm1.Button1Click(Sender: TObject); begin // 필드 추가 memList.FieldDefs.Add('ID', ftInteger, 0, False); memList.FieldDefs.Add('Name', ftString, 20, False); memList.CreateDataSet; memList2.FieldDefs.Add('ID', ftInteger, 0, False); memList2.FieldDefs.Add('Name', ftString, 20, False); memList2.CreateDataSet; memDetail.FieldDefs.Add('ID', ftInteger, 0, False); memDetail.FieldDefs.Add('Name', ftString, 20, False); memDetail.FieldDefs.Add('addr', ftString, 50, False); memDetail.CreateDataSet; // 데이터 추가 memList.Open; memList.AppendRecord([1, '김현수']); memList.AppendRecord([2, '홍길동']); memList.AppendRecord([3, '유관순']); memList2.Open; memList2.AppendRecord([4, '김원경']); memList2.AppendRecord([5, '박범용']); memDetail.Open; memDetail.AppendRecord([1, '김현수', '인천']); // Field 복사: 미리 복사하지 않으면 Detail 머지 시 PK 설정되지 않음 memMerge.MergeDataSet(memDetail, dmNone, mmMerge); // 병합해 넣을 데이터셋(memMerge)에 기본키가 설정되어 있어야 함. 기본키가 없으면 'no destination key defined' 오류 발생 memMerge.Table.PrimaryKey := memDetail.Table.PrimaryKey; end; procedure TForm1.Button3Click(Sender: TObject); begin memMerge.MergeDataSet(memList, dmDataMerge, mmNone); end; procedure TForm1.Button4Click(Sender: TObject); begin memMerge.MergeDataSet(memList2, dmDataMerge, mmNone); end; procedure TForm1.Button5Click(Sender: TObject); begin memMerge.MergeDataSet(memDetail, dmDataMerge, mmNone); end;
참고
- http://docwiki.embarcadero.com/Libraries/Seattle/en/FireDAC.Comp.DataSet.TFDDataSet.MergeDataSet
- http://docwiki.embarcadero.com/Libraries/Seattle/ja/FireDAC.Stan.Intf.TFDMergeDataMode
- http://docwiki.embarcadero.com/Libraries/Seattle/ja/FireDAC.Stan.Intf.TFDMergeMetaMode