[FireDAC MergeDataSet] 여러 데이터셋을 병합해 하나의 데이터셋을 구성할 수 있습니다.

2016.02.05 13:13

FireDAC의 TFDDataSet.MergeDataSet 메소드를 이용해 구조가 같은(또는 확장된) 데이터셋을 병합해 하나의 데이터셋을 구성할 수 있습니다.


제가 테스트한 목적은, 

데이터스냅으로 데이터량이 많은 데이터 중 일부분 데이터만 가져오고, 필요한 경우 추가로 가져와 병합(페이징 기능 구현) 할 목적으로 테스트 진행해 봤습니다.

TFDDataSet.MergeDataSet

지정된 데이터 셋(ASource)의 데이터와 메타데이터를 현재 데이터셋과 병합합니다.

procedure MergeDataSet(ASource: TFDDataSet; AData: TFDMergeDataMode = dmDataMerge; AMeta: TFDMergeMetaMode = mmNone);


TFDMergeDataMode

데이터셋 데이터를 병합하는 방법 지정

모드설명

데이터셋 변경 사항 커밋

dmNone

데이터를 병합하지 않습니다.

-

dmDataSet

원 데이터셋 클리어 후 지정된 데이터셋의 레코드를 대신 삽입합니다.

dmDataAppend

지정된 데이터셋의 레코드를 원 데이터셋에 덧붙입니다.

dmDataMerge

지정된 데이터셋의 레코드의 기본 키를 취득하고 그것과 같은 기본 키 대응 레코드를 원 데이터셋에서 찾습니다. 그 후 다음 중 하나를 수행합니다.

  • 이 데이터셋의 레코드에 해당하는 레코드가 지정된 데이터셋에있는 경우, 해당 레코드에서이 데이터셋의 레코드를 업데이트합니다.
  • 지정된 데이터셋의 레코드에 해당하는 레코드가이 데이터셋에 없는 경우는 지정된 데이터셋의 레코드가 새 레코드로이 데이터셋에 추가됩니다.
  • 해당 레코드가 삭제 된 레코드가 있으면 그것을 삭제합니다.

dmDeltaSet

원 데이터셋을 지우고 지정된 데이터셋의 레코드를 대신 삽입합니다.

아니오

dmDeltaAppend

지정된 데이터셋의 레코드를 원 데이터셋에 덧붙입니다.

아니오

dmDeltaMerge

지정된 데이터셋의 레코드의 기본 키를 취득하고 그것과 같은 기본 키 대응 레코드를 원 데이터셋에서 찾습니다. 그 후 다음 중 하나를 수행합니다.

  • 이 데이터셋의 레코드에 해당하는 레코드가 지정된 데이터셋에있는 경우, 해당 레코드에서이 데이터셋의 레코드를 업데이트합니다.
  • 지정된 데이터셋의 레코드에 해당하는 레코드가이 데이터셋에 없는 경우는 지정된 데이터셋의 레코드가 새 레코드로이 데이터셋에 추가됩니다.
  • 해당 레코드가 삭제 된 레코드가 있으면 그것을 삭제합니다.

아니오

TFDMergeMetaMode

데이터셋 메타데이터 병합하는 방법 지정

모드설명
mmNone메타 데이터의 비교 및​​ 병합을하지 않습니다.
mmMerge

지정된 데이터 집합에서 열 이름을 검색하여 이름이 같은 열이 데이터셋에서 찾습니다. 그 후 다음 중 하나를 수행합니다.

  • 지정된 데이터셋의 메타 데이터에서이 데이터셋의 열의 데이터 형식과 크기를 업데이트합니다 (같은 이름의 열만).
  • 같은 이름의 열이 데이터셋에서 찾을 수없는 경우 새 열을 데이터셋에 추가합니다.
mmAdd

지정된 데이터 집합에서 열 이름을 검색하여 이름이 같은 열이 데이터셋에서 찾습니다. 같은 이름의 열이 데이터셋에서 찾을 수없는 경우 새 열을 데이터셋에 추가합니다.

mmUpdate

지정된 데이터 집합에서 열 이름을 검색하여 이름이 같은 열이 데이터셋에서 찾습니다. 같은 이름의 열이 데이터셋에서 발견 된 경우 해당 열의 데이터 형식과 크기를 지정된 데이터셋의 메타 데이터로 업데이트합니다.

mmAddOrError

이 데이터셋의 메타 데이터를 다음과 같이 업데이트합니다.

  • 이 데이터셋에 열이없는 경우는 mmAdd 모드를 적용합니다.
  • 그렇지 않으면 mmError 모드를 적용합니다.
mmError

지정된 데이터 집합에서 열 이름을 검색하여 이름이 같은 열이 데이터셋에서 찾습니다. 동명의 열이 없거나, 동명의 열 데이터 형식이나 크기가 일치하지 않는 경우는 예외를 전달합니다.

TFDDataSet.MergeDataSet 데모


해당 데모는 왼쪽에 표시되는 3개 데이터셋(memList, memList2, memDetail)을 병합해 오른쪽에 표시되는 데이터셋(memMerge)으로 병합합니다.

병합할 대상 데이터는 같은 구조(ID, Name)의 데이터셋 2개와 확장된 구조(ID, Name, addr)를 데이터셋을 병합합니다.


작성하며 주의할 점은, 

  1. 병합해 넣을 데이터셋(memMerge)에 기본키가 설정되어 있어야 합니다. => 아래 코드에서 "memMerge.Table.PrimaryKey := memDetail.Table.PrimaryKey;"
  2. 필드 종류가 다른 데이터셋(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;

참고



저작자 표시 비영리 동일 조건 변경 허락
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

험프리.김현수 험프리.김현수 FireDAC FireDAC

[FireDAC Skill Sprints] 9. LocalSQL: DB에서 가져온 데이터(데이터셋)를 대상으로 다시 SQL쿼리 실행하기

2015.03.31 16:13

엠바카데로에서 FireDAC Skill Sprint 웨비나(1월 23일 ~ 3월 27일: 매주 금요일 10시)를 진행하고 있습니다.


이 글에서는 웨비나 다시보기와 함께 웨비나 일부 내용을 샘플코드와 함께 소개합니다. 하단 온라인 기술 도움말 링크를 통해 더 자세한 내용을 추가학습하시기 바랍니다.


9회차에서는 쿼리 결과에서 검색하고, 조인할 수 있는 Local SQL에 대해 알아봅니다.


Local SQL이란?

Local SQL은 DB로부터 애플리케이션의 메모리 상으로 가져온 데이터(데이터셋: TDataSet을 상속받은 객체)를 대상으로 다시 SQL 쿼리를 할 수 있는 기능입니다.


Local SQL은 아래와 같이 사용할 수 있습니다.

  • 여러 이기종 DB들에 대한 쿼리 : 다양한 DB에서 가져온 여러 데이터셋을 대상으로 원하는 데이터 쿼리(조인 가능)
  • 인 메모리 데이터베이스 : TFDMemTable은 메모리상에 있는 데이터셋의 역할
  • 오프라인 모드 쿼리 : 원격 DB에 연결할 수 없는 경우에도, 이미 가져온 데이터셋을 대상으로 쿼리 실행
  • 데이터스냅 클라이언트 쿼리 : 데이터스냅 서버(미들웨어)에서 받아온 데이터셋을 대상으로 쿼리 실행
  • 간편한 마이그레이션 : 애플리케이션 내에서 써드파티를 통해 가져온 데이터셋 객체를 대상으로 쿼리 실행

용어> 데이터셋(DataSet) = 애플리케이션의 메모리 상에 있는 데이터 집합


Local SQL 사용을 위한 FireDAC 컴포넌트 구성

  • TFDConnection의 DriverName을 SQLite로 설정합니다.(FireDAC의 Local SQL 엔진으로 SQLite 드라이버를 사용합니다.)
  • TFDLocalSQL과 TFDQuery 컴포넌트의 Connection을 위의 TFDConnection으로 설정
  • TFDLocalSQL 컴포넌트의 DataSets 컬랙션(속성)에 조회할 데이터셋(TDataSet을 상속받은 객체)을 등록

Local SQL의 설정의 자세한 내용은 엠바카데로 기술문서 - Local SQL (FireDAC) 페이지를 참고하시기 바랍니다.


Local SQL 샘플 프로그램

샘플 프로그램에서는 TFDLocalSQL 컴포넌트를 이용해 5가지의 서로 다른 유형의 데이터셋에서 필요한 데이터만 조회해 그리드에 표시합니다.

[샘플코드는 http://delphi.org/2015/03/firedac-local-sql/에서 받을 수 있습니다.]


샘플에서 중점적으로 확인할 내용

    • 총 5 종류의 서로다른 데이터를 대상으로 쿼리
      • dbExpress : dbExpress를 이용해 데이터베이스에서 가져온 데이터
      • REST CDS : REST Client를 이용해 웹서비스에서 가져온 데이터
      • IBX : IBX를 이용해 인터베이스 DB에서 가져온 데이터
      • MemTable from Code : 코드로 직접 만든 로컬 데이터
      • ADO & Access : ADO 기술을 이용해 엑세스 DB에서 가져온 데이터
    • FDLocalSQL1의 DataSets 컬랙션에는 5개의 데이터셋을 검색 대상으로 등록
    • FDQuery1에서는 FDLocalSQL1.DataSets에 등록된 데이터셋 대상으로 SQL 쿼리를 작성해 검색할 수 있습니다.
    SELECT 
      sales.order_status, 
      customers.customer,
      regions.RegionDescription, 
      rest.name as REP
    FROM rest 
    
    INNER JOIN RestSalesReps 
    ON rest.id = RestSalesReps.RestID
    
    INNER JOIN Sales
    ON RestSalesReps.Sales_Rep = Sales.Sales_REP
    
    INNER JOIN customers
    ON sales.cust_no = customers.cust_no
    
    LEFT OUTER JOIN regions
    ON regions.RegionID = RestSalesReps.RestID


    저작자 표시 비영리 동일 조건 변경 허락
    신고
    크리에이티브 커먼즈 라이선스
    Creative Commons License

    험프리.김현수 험프리.김현수 FireDAC FireDAC, FireDAC Skill Sprints, LocalSQL

    [FireDAC Skill Sprints] 1. FireDAC 동영상과 샘플로 고급기능 활용하기

    2015.03.24 16:47

    엠바카데로에서 FireDAC Skill Sprint 웨비나(1월 23일 ~ 3월 27일: 매주 금요일 10시)를 진행하고 있습니다.


    이 글에서는 웨비나 다시보기와 함께 웨비나 일부 내용을 샘플코드와 함께 소개합니다. 하단 온라인 기술 도움말 링크를 통해 더 자세한 내용을 추가학습하시기 바랍니다.


    1회차에서는 FireDAC을 소개하고 연결하는 과정으로 진행합니다.

    FireDAC 소개

    FireDAC은 델파이와 C++빌더에서 멀티-디바이스 데이터베이스 애플리케이션을 개발할 수 있는 범용(Universal) 데이터 엑세스 컴포넌트입니다. 


    FireDAC은 통합 API를 사용해 다양한 데이터베이스를 동일한 코드로 제어할 수 있습니다. 그렇기 때문에 개발자는 데이터베이스를 신경쓰지 않고 애플리케이션 개발에 집중할 수 있고, DBMS 변경 시 대부분의 코드를 재사용할 수 있습니다. 그 뿐아니라 FireDAC은 데이터베이스 별 고유기능을 사용하고, 최적의 성능을 발휘할 수 있도록 데이터베이스 별 네이티브 드라이버를 지원합니다.


    또한 기술적으로 아래의 장점을 제공합니다.

    • 30배 빠른 데이터 입력이 가능한 Array DML
    • DBMS의 사용내역을 추적하고 모니터링
    • 엑셀형식으로 내보내고, 가져오기 기능을 개발할 수 있는 Batch Move
    • DB에서 가져온 메모리상의 데이터를 대상으로 쿼리할 수 있는 Local SQL
    • 이 외의 기술적인 장점은 아래의 FireDAC Skill Sprints 동영상과 샘플로 고급기능 활용하기 시리즈로 직접 확인하시기 바랍니다. 


    FireDAC의 자세한 소개는 데브기어 FireDAC 소개페이지와 FireDAC 기술문서 - Overview를 참고할 수 있습니다.

    FireDAC Skill Sprints 동영상과 샘플로 고급기능 활용하기

    2. FireDAC으로 DBMS 사용 내역 추적, 모니터링 하기

    FireDAC 추적기능을 이용하면 애플리케이션과 데이터베이스 사이의 통신내용을 상세하게 보거나 기록할 수 있습니다. 이 추적 정보에는 이벤트 발생시간, API 호출내역, DB로 전송된 SQL 문, 파라메터와 필드 값, 오류와 경고 등이 기록되어 여러분의 DB 애플리케이션의 문제점을 디버깅하고 해결하는데 유용하게 사용할 수 있습니다.


    샘플에서는 데이터 조회(테이블 오픈) 시 애플리케이션과 DBMS의 통신내용을 모니터링 유틸리티(FireDAC Monitor)로 확인하고, DB 애플리케이션 디버깅 시 유용한 메터데이터(DBMS 객체 정보)를 이용해 테이블, 필드, 제너레이터, 스토어드 프로시저 목록을 조회해 봅니다.

    3. 캐쉬를 이용한 업데이트와 자동증가필드(Identity) 적용

    캐쉬 업데이트는 애플리케이션의 메모리 영역(즉, 데이터셋)에 업데이트 내역을 기록하고, DBMS에 한번에 업데이트(또는 일괄취소) 할 수 있는 기능입니다. 

    캐쉬 업데이트를 사용하면 작업내용을 로컬에서 관리하므로 DBMS와의 트래픽을 줄일 수 있고, 사용자는 통신속도와 관계없이 빠른 작업이 가능합니다. 그리고 작업이력을 확인(변경된 레코드 조회, 변경된 항목의 이전 값 확인 등)하고, 작업 변경취소(마지막 작업 변경취소, 선택한 레코드 변경취소 등)을 FireDAC에서 제공하는 메소드를 이용해 손쉽게 구현할 수 있습니다.


    샘플에서는 캐쉬 업데이트를 이용해 조회한 데이터를 메모리 상에서 편집(입력, 수정, 삭제) 후 업데이트 목록 표시, 변경취소, 일괄적용/취소 기능을 구현해 봅니다.

    Array DML은 DBMS에 업데이트할 데이터를 배열 형태의 파라메터로 한번에 전송해 아주 빠르게 데이터를 입력할 수 있는 기능입니다.

    Array DML을 사용하면 DBMS와 애플리케이션 사이의 통신비용을 줄이고 DBMS에 전송하는 요청 횟수를 현격히 줄입니다. 그 결과 실행 속도를 대폭 향상시킬 수 있습니다.

    예를 들면, 1만건의 데이터 입력 시 반복 입력 작업을 트랜젝션으로 묶으면 20배 빨라지고, Array DML을 사용하면 다시 10배가 더 빨라집니다. 샘플을 통해 결과를 직접 확인해 보기 바랍니다.

    FireDAC에는 검색옵션, 형식옵션, 업데이트옵션, 리소스옵션, 트랜젝션옵션 등의 수많은 옵션을 제공합니다.

    이 글에서는 주요 옵션을 살펴봅니다. 주요 옵션을 살펴보고 필요한 옵션은 상세확인 해 여러분의 애플리케이션을 향상해 보기 바랍니다.


    샘플에서는 데이터 지연 조회(DetailDelay), 데이터 페이징 단위 조회(RecsSkip, RecsMax)과 같은 고급 기능을 FireDAC 옵션을 이용해 손쉽게 구현해 봅니다.

    커맨드 텍스트 전처리는 SQL 명령을 데이터베이스에 전달하기 전 파라메터를 치환하고, FireDAC 매크로 함수를 DBMS에 맞도록 치환하는 기능입니다.

    전처리 기능은 아래 3 종류의 매크로 명령을 제공합니다.

    • 매개변수를 확장할 수 있는 대체변수
    • 한번 작성 후 다양한 DBMS에서 사용할 수 있는 SQL문 작성하는 이스케이프 시퀀스
    • 연결된 DBMS에 따라 조건부로 실행되는 SQL문을 작성하는 조건부 대체 

    샘플에서는 매크로 대체변수를 이용해 데이터 탐색기를 만들고, 이스케이프 시퀀스로 작성된 통합 SQL문이 실제 DBMS에 전달 시 어떻게 변환되는지 확인해 봅니다.

    FireDAC의 ETL은 Extract, Transform, Load의 약자로 아래의 역할을 의미합니다. 

    • Extract(추출) : 같은 종 또는 이기종 데이터 소스로부터 데이터를 추출 
    • Transform(변환) : 추출한 데이터를 분석용 데이터 형식 또는 입력쿼리로 변환
    • Load(로드) : 최종 목적(데이터베이스, 운용 데이터 저장소, 데이터 마트, 또는 데이터 창고)으로 로드 

    FireDAC ETL로 아래의 기능을 구현할 수 있습니다.(몇가지 예시입니다.) 

    • Query문으로 조회한 데이터를 엑셀에서 사용할 수 있는 CSV 파일로 내보내기
    • 텍스트파일의 데이터를 데이터베이스 테이블로 가져오기
    • 데이터베이스에서 다른 데이터베이스로 데이터 이동하기

    샘플에서는 위 3가지 기능을 직접구현해 봅니다. 컴포넌트 구성과 컴포넌트 속성을 참고할 수 있습니다.

    8. TFDMemTable: 메모리 기반 데이터셋 사용하기

    TFDMemTable은 메모리 기반 데이터셋입니다. 즉, 데이터베이스 연결 없이 파일 데이터나 코드로 추가한 데이터를 메모리에 올려 데이터셋의 기능(필터링, 정렬 등)을 사용할 수 있습니다.


    TFDMemTable은 아래 기능을 할 수 있습니다.

    • 디자인타임과 런타임 시 파일 불러오기(Load File), 파일로 내보내기(Save File), 다른 데이터셋의 데이터가져오기(Assign Data) 기능 사용
    • 런타임 시 파일과 스트림으로 데이터 내보내기, 불러오기 기능을 사용할 수 있으며, JSON, XML, Binary 포맷 선택 가능
    • 멀티티어 애플리케이션(REST 클라이언트, 데이터스냅 등)에서 수신 데이터를 보관하는 데이터셋 역할
    • 내부에서 데이터 보관할 시 컬랙션객체(TList, TStringList) 대신 메모리테이블 사용 시 데이터셋의 기능(UI 컨트롤에 데이터바인딩, Local SQL, 필터링, 정렬 등)을 사용해 다양한 기능 손쉽게 구현가능
    • Local SQL을 이용해 메모리테이블(데이터셋)에서 쿼리 실행
    • ETL 기능으로 다른 데이터소스(텍스트, CSV 등)에서 가져온 데이터 보관

    Local SQL은 DB로부터 애플리케이션의 메모리 상으로 가져온 데이터(데이터셋: TDataSet을 상속받은 객체)를 대상으로 다시 SQL 쿼리를 할 수 있는 기능입니다. Local SQL은 아래와 같이 사용할 수 있습니다. 

    • 여러 이기종 DB들에 대한 쿼리 : 다양한 DB에서 가져온 여러 데이터셋을 대상으로 원하는 데이터 쿼리(조인 가능) 
    • 인 메모리 데이터베이스 : TFDMemTable은 메모리상에 있는 데이터셋의 역할 
    • 오프라인 모드 쿼리 : 원격 DB에 연결할 수 없는 경우에도, 이미 가져온 데이터셋을 대상으로 쿼리 실행 
    • 데이터스냅 클라이언트 쿼리 : 데이터스냅 서버(미들웨어)에서 받아온 데이터셋을 대상으로 쿼리 실행 
    • 간편한 마이그레이션 : 애플리케이션 내에서 써드파티를 통해 가져온 데이터셋 객체를 대상으로 쿼리 실행
    샘플에서는 Local SQL을 이용해 dbExpress, REST Client, 메모리테이블 등 총 5종류의 이기종의 데이터셋을 조인한 데이터를 그리드에 출력합니다.

    10. BDE 프로젝트를 FireDAC으로 마이그레이션 하기

    (준비 중)


    관련링크



    저작자 표시 비영리 동일 조건 변경 허락
    신고
    크리에이티브 커먼즈 라이선스
    Creative Commons License

    험프리.김현수 험프리.김현수 FireDAC FireDAC, Skill Sprints

    [FireDAC Skill Sprints] 6. 전처리: SQL문을 유연하게 작성할 수 있는 Param와 Macro 사용하기

    2015.03.12 17:55

    엠바카데로에서 FireDAC Skill Sprint 웨비나(1월 23일 ~ 3월 27일: 매주 금요일 10시)를 진행하고 있습니다.


    이 글에서는 웨비나 다시보기와 함께 웨비나 일부 내용을 샘플코드와 함께 소개합니다. 하단 온라인 기술 도움말 링크를 통해 더 자세한 내용을 추가학습하시기 바랍니다.


    6회차에서는 커맨드 텍스트 전처리에 관한 내용으로 진행합니다.


    커맨드 텍스트 전처리란?

    커맨드 텍스트 전처리는 SQL 명령을 데이터베이스에 전달하기 전 파라메터를 치환하고, FireDAC 매크로 함수를 DBMS에 맞도록 치환하는 기능입니다.


    FireDAC 은 커맨드 텍스트 전처리 작업할 수 있는 3가지의 매크로 명령을 지원합니다.

    • 대체변수(Substitution variables) : 파라메터 확장을 위해 SQL 문의 일부를 치환. 예를 들면 FROM절의 테이블이름과 SELECT 절의 필드명을 파라메터화 하려면 대체변수를 사용해야 함
    • 이스케이프 시퀀스(Escape sequences) : 한번 작성하면 서로 다른 DBMS에서 그대로 사용할 수 있는 DBMS에 의존적이지 않은 SQL문 생성
    • 조건부 대체(Conditional substitutions) : 연결된 DBMS에 따라 조건부로 실행되는 SQL 문 작성

    대체변수

    FDQuery1.SQL.Text := 'SELECT * FROM &TabName';
    FDQuery1.MacroByName('TabName').AsRaw := 'Orders';
    FDQuery1.Open;

    • 위와 같이 매크로 변수(&TabName)를 이용해 SQL 문 작성 후  MacroByName 메소드를 이용해 내용을 치환할 수 있습니다.

    이스케이프 시퀀스

    FireDAC은 다음 5가지 이스케이프 시퀀스가 있습니다.

    • 상수 치환
    • 식별자 치환
    • 조건부 대체
    • Like 연산자 이스케이프 시퀀스
    • 스칼라 함수

    그중 상수 치환 이스케이프 시퀀스를 사용하면 DBMS의 구문 및 지역설정과 관계없이 커맨드 텍스트 상수를 작성할 수 있습니다. 예를 들면 아래와 같습니다.

    • {d <날짜>} : {d 2014-08-30}은 Oracle에서 TO_DATE{'2014-08-30', 'yyyy-mm-dd'} 입니다.
    • {t <시간>} : {t 14:30:00}은 SQL Server에서 CONVERT (DATETIME, '14 : 30 : 00 ', 114) 입니다.(hh24:mi:ss 형식으로 작성해야 합니다.)
    • {id <식별자명>} : 식별자명이 DBMS의 고유 구문으로 치환됩니다.

    조건부 대체

    조건부 대체는 연결된 DBMS(또는 매크로 변수 값)에 따라 명령을 대체합니다. 예를 들면 아래와 같습니다.

    • {IF Oracle} TO_CHAR{fi} {IF MSSQL} CONVERT {fi} : 오라클인 경우 TO_CHAR, MSSQL인 경우 CONVERT 명령어로 실행됩니다.
    자세한 커맨드 텍스트 전처리 설명과 내용은 엠바카데로 기술문서 - Preprocessing Command Text (FireDAC)를 참고하시기 바랍니다.

    ❑ Preprocessing 샘플 프로그램 소개

    이 샘플에서는 총 2가지 기능을 소개합니다.

    • 테이블을 선택 후 해당 테이블의 필드를 (다중)선택 하면 매크로의 대체변수를 이용해 SQL 쿼리를 작성해 데이터를 조회합니다.

    • 이스케이프 시퀀스를 이용해 작성한 쿼리 수행 후 FireDAC 모니터를 통해 최종적으로 실행되는 SQL 쿼리와 비교합니다.

    [샘플코드 받기 - 데브기어 github 페이지]


    매크로 대체변수로 필드목록과 테이블명 선택 해 데이터 조회하기

    첫번째 탭에 구현된 기능으로 테이블 목록에서 테이블 선택 후 필드(다중선택) 목록에서 조회할 필드를 체크 후 "선택 데이터 표시" 버튼을 누르면 그리드에 데이터가 표시됩니다.

    쿼리컴포넌트에는 아래와 같이 필드목록(&FieldList)와 대상 테이블명(&TableName)을 매크로 대체변수로 작성했습니다.

    SELECT &FieldList FROM &TableName

    델파이에서는 아래 코드와 같이 Macro 값을 설정하고 쿼리를 실행하면 SQL 문이 실행되기 전 필드목록과 테이블명이 치환되어 SQL 문이 실행됩니다.

      DM.qrySelect.MacroByName('FieldList').AsRaw := FieldList;
      DM.qrySelect.MacroByName('TableName').AsRaw := ListBox1.Selected.Text;
      DM.qrySelect.Open;


    이스케이프 시퀀스로 DBMS 의존적이지 않은 SQL문 작성

    이스케이프 시퀀스는 

    1. FireDAC 매크로 함수를 이용해 DBMS에 의존적이지 않은 SQL문을 작성합니다.
    2. 매크로 함수가 포함된 SQL 문은 실행 전 DBMS에 맞는 DBMS 함수로 치환되어 SQL 문이 실행됩니다.


    쿼리 컴포넌트에는 아래와 같이 매크로 함수가 포함된 SQL문을 작성했습니다.

    SELECT {Current_Date()} as Today, c.*
      FROM &TabNam c
     WHERE {Extract(Year, c.SaleDate)} = {e 1988}

    애플리케이션을 실행하고 FireDAC 모니터링 기능을 이용해 처리된 SQL 문을 확인하면 아래와 같이 DBMS의 함수로 치환되어 SQL 문이 실행됩니다.


    매크로 함수는 아래와 같습니다.


    저작자 표시 비영리 동일 조건 변경 허락
    신고
    크리에이티브 커먼즈 라이선스
    Creative Commons License

    험프리.김현수 험프리.김현수 FireDAC FireDAC, preprocessing

    [FireDAC Skill Sprints] 5. Cascading Options: 고급기능을 활용 할 수 있는 FireDAC 옵션

    2015.03.11 14:22

    엠바카데로에서 FireDAC Skill Sprint 웨비나(1월 23일 ~ 3월 27일: 매주 금요일 10시)를 진행하고 있습니다.


    이 글에서는 웨비나 다시보기와 함께 웨비나 일부 내용을 샘플코드와 함께 소개합니다. 하단 온라인 기술 도움말 링크를 통해 더 자세한 내용을 추가학습하시기 바랍니다.


    5회차에서는 FireDAC의 캐스캐이딩 옵션에 대해 소개하고 살펴봅니다.

    FireDAC 캐스캐이딩 옵션

    FireDAC에는 5종류의 옵션 그룹을 제공합니다.

    • FetchOptions : DBMS에서 데이터를 어떻게 취득할지 제어하는 검색 옵션입니다.
    • FormatOptions : DBMS의 데이터형식을 FireDAC 데이터 형식으로 또는 반대로 매핑하는 방법을 제어하는 형식 옵션입니다.(자세한 내용은 "Data Type Mapping"을 참조하세요.)
    • UpdateOptions : DBMS에 업데이트 전송 방법을 제어하는 업데이트 옵션입니다. 업데이트 시 테이블의 모든 필드를 업데이트하거나 변경된 필드만 업데이트 할 수 있습니다.
    • ResourceOptions : 시스템 리소스 사용과 데이터셋의 지속성을 제어하는 자원 옵션입니다. 예를 들면 FireDAC Phys 레이어 명령을 비동기 적으로 실행 또는 차단할 수 있습니다.
    • TxOptions : 트랜젝션 실행방법을 제어하는 트랜젝션 옵션입니다. 


    위의 옵션은 Manager > Connection > DataSet/Command로 캐스캐이딩(위에서 아래로 적용) 됩니다. 즉, TFDConnection에 옵션을 설정하면 해당 연결을 사용하는 TFDQuery, TFDTable도 동일한 옵션이 적용됩니다.(일부 옵션 제외)

    FireDAC 카테고리 별 주요옵션

    다음은 FireDAC 주요옵션을 카테고리별로 나열한 것입니다. 각 옵션에 대한 자세한 내용은 항목 아래 기술문서 링크에 방문해 상세 설명을 보시기 바랍니다.


    검색옵션(FetchOptions)

    • 취득 방법 ( CursorKind , Mode , RowsetSize ). 예를 들어, 결과 세트의 모든 레코드를 한 번에 검색 할 수 주문형 레코드를 검색 할 수 있습니다. 
    • 자원 보존 방법 ( Unidirectional , AutoClose , Cache , AutoFetchAll ). 
    • BLOB 필드 중첩 된 레코드 메타 데이터 검색 및 캐시 방법 ( Items , Cache ). 
    • 마스터/디테일 데이터셋 관계의 처리 방법 ( DetailDelay , DetailOptimize , DetailCascade ). 
    • 행 집합 페이징 ( RecsMax , RecsSkip ). 
    • TFDTable 작동 모드 ( CursorKind , LiveWindowParanoic , LiveWindowFastFirst ). 
    • 데이터 집합의 레코드를 세는 방법 ( RecordCountMode ).

    TFDFetchOptions 기술문서 - http://docwiki.embarcadero.com/Libraries/XE7/en/FireDAC.Stan.Option.TFDFetchOptions


    형식옵션(FormatOptions)

    • 문자열 데이터 형식 ( StrsEmpty2Null , StrsTrim , StrsTrim2Len , InlineDataSize , MaxStringSize ) 
    • 숫자 데이터 형식 ( MaxBcdPrecision , MaxBcdScale , Round2Scale ) 
    • 시간 데이터 형식 ( Round2Scale ) 
    • 일반적인 데이터 형식 매핑 ( MapRules , OwnMapRules , DefaultParamDataType ). 예를 들어 NUMERIC (9, 0)의 열을 ftInteger 컬럼에 맵핑 할 수 있습니다. 
    • 필드 형식 ( FmtDisplayDateTime , FmtDisplayDate , FmtDisplayTime , FmtDisplayNumeric , FmtEditNumeric ) 
    • 데이터 집합의 정렬 ( SortLocale , SortOptions ) 
    • 식별자 따옴표 ( QuoteIdentifiers )

    TFDFormatOptions 기술문서 - http://docwiki.embarcadero.com/Libraries/XE7/en/FireDAC.Stan.Option.TFDFormatOptions


    업데이트옵션(UpdateOptions)

    • 데이터 편집 허용 ( EnableDelete , EnableInsert , EnableUpdate , ReadOnly , CheckRequired , CheckReadOnly , CheckUpdatable ). 여기에는 TField.ReadOnly 과 TField.Required 도 영향을줍니다. 
    • 데이터베이스 레코드 잠금 ( LockMode , LockPoint , LockWait ). 
    • 자동 증가 필드에 대한 데이터베이스 생성기와 시퀀스의 사용 ( FetchGeneratorsPoint , GeneratorName ). 여기에는 TField.AutoGenerateValue 도 영향을줍니다. 
    • 업데이트 사후 명령의 생성 ( UpdateChangedFields , UpdateNonBaseFields , UpdateMode , FastUpdates ). 여기에는 TField.ProviderFlags 과 TField.Origin 도 영향을줍니다. 
    • 데이터의 업데이트 ( RefreshMode , RefreshDelete ). 
    • 업데이트 포스트 결과 확인 ( CountUpdatedRecords ).

    TFDUpdateOptions 기술문서 - http://docwiki.embarcadero.com/Libraries/XE7/en/FireDAC.Stan.Option.TFDUpdateOptions


    리소스옵션(ResourceOptions)

    • SQL 명령 텍스트 전처리 ( EscapeExpand , MacroCreate , MacroExpand , ParamCreate , ParamExpand , PreprocessCmdText , UnifyParams ). 
    • 명령의 준비 ( DirectExecute , DefaultParamType ). 
    • 명령 실행 ( CmdExecMode , CmdExecTimeout , ArrayDMLSize ). 
    • 자원 관리 ( SilentMode ). 
    • 데이터 집합 지속성 ( Persistent , Backup , BackupExt , BackupFolder , DefaultStoreExt , DefaultStoreFolder , DefaultStoreFormat , StoreVersion , StoreItems ).

    TFDResourceOptions 기술문서 - http://docwiki.embarcadero.com/Libraries/XE7/en/FireDAC.Stan.Option.TFDResourceOptions


    트랜젝션옵션(TxOptions)

    • 독점적 수준 ( Isolation ) 
    • 업데이트 기능 ( ReadOnly ) 
    • 자동 커밋 ( AutoCommit , AutoStart , AutoStop , StopOptions ) 
    • DBMS 고유의 파라미터 ( Params ) 
    • 액션 연결 해제 ( DisconnectAction ) 중첩 ( EnableNested )

    TFDTxOptions 기술문서 - http://docwiki.embarcadero.com/Libraries/XE7/en/FireDAC.Stan.Option.TFDTxOptions

    FireDAC 옵션 샘플프로그램

    이 샘플에서는 FetchOptions을 이용해 아래 3가지 기능을 구현했습니다.

    • 테이블에 데이터가 많은 경우 신속하게 화면에 표시하기 위해 데이터를 나눠서 가져오기(FetchOptions.RowsetSize, FetchOptions.Mode 이용)
    • 데이터를 페이징 단위(중간의 데이터 만)로 조회(FetchOptions.RecsSkip, RecsMax 이용)
    • 마스터/디테일 형식의 화면에서 키보드로 목록을 빠르게 움직여도 마지막에 위치한 상세정보만 표시해 불필요한 데이터 조회 방지(FetchOptions.DetailDealy 이용)

    [샘플코드 받기 - 데브기어 github 페이지]


    데이터를 지정건수 만큼 나눠서 가져오는 기능
    데이터가 많은 경우 전체 데이터를 가져와 화면에 표시하는 것 보다 부분적으로 표시하고 추가로 데이터를 표시하는 것이 효과적일 수 있습니다.
    FireDAC에서는 FetchOption의 Mode와 RowsetSize를 설정해 해당 기능을 구현할 수 있습니다. 다음 데이터목록을 가져오려면 TFDQuery.FetchNext 메소드를 호출합니다.
      qryEmployee.Close;
      if TCheckBox(Sender).Checked then
      begin
        qryEmployee.FetchOptions.RowsetSize := 3;
        qryEmployee.FetchOptions.Mode := TFDFetchMode.fmManual;
      end
      else
      begin
        qryEmployee.FetchOptions.Mode := TFDFetchMode.fmOnDemand;
      end;
      qryEmployee.Open;
      btnFetchNext.Enabled := TCheckBox(Sender).Checked;

    데이터 페이징 단위로 조회 기능
    페이징 단위로 데이터를 조회할 수 있습니다. DBMS 자체에서 Top, Limit 명령을 통해 쿼리로 수행하던 기능을 FireDAC 컴포넌트로 구현할 수 있습니다.
      qryEmployee.Close;
      qryEmployee.FetchOptions.RecsSkip := 10;
      qryEmployee.FetchOptions.RecsMax := 10;
      qryEmployee.Open;

    상세 데이터 조회지연 기능 구현
    사원정보(qryEmployee)와 사원이 진행한 프로젝트(qryProject)로 목록/상세 기능 구현 후 체크박스(chkFetchRowsetSize) 체크 시 DetailDelay 옵션으로 지연 조회 하도록 설정
      if TCheckBox(Sender).Checked then
        qryProject.FetchOptions.DetailDelay := StrToIntDef(Edit1.Text, 300)
      else
        qryProject.FetchOptions.DetailDelay := 0;

    관련 링크



    저작자 표시 비영리 동일 조건 변경 허락
    신고
    크리에이티브 커먼즈 라이선스
    Creative Commons License

    험프리.김현수 험프리.김현수 FireDAC Cascading Options, FetchOption, FireDAC, Skill Sprints

    [FireDAC Skill Sprints] 2. FireDAC으로 DBMS 사용 내역 추적, 모니터링 하기

    2015.02.17 11:09

    엠바카데로에서 FireDAC Skill Sprint 웨비나(1월 23일 ~ 3월 27일: 매주 금요일 10시)를 진행하고 있습니다.


    이 글에서는 웨비나 다시보기와 함께 웨비나 일부 내용을 샘플코드와 함께 소개합니다. 하단 온라인 기술 도움말 링크를 통해 더 자세한 내용을 추가학습하시기 바랍니다.


    2회차에서는 FireDAC의 추적과 모니터링에 대한 내용으로 진행합니다.

    FireDAC 추적과 모니터링

    FireDAC의 추적기능을 이용하면 애플리케이션과 데이터베이스 사이의 통신내용을 상세하게 보거나 기록할 수 있습니다. 

    이 추적 정보에는 이벤트 발생시간, API 호출내역, DB로 전송된 SQL, 파라메터와 필드 값, 오류와 경고 등이 기록되어 여러분의 DB 애플리케이션으 문제점을 디버깅하고 해결하는데 유용하게 사용할 수 있습니다.

    (주의 : 추적과 모니터링 기능은 애플리케이션의 성능에 영향을 줄 수 있습니다. 디버그 모드에서만 추적기능이 동작하도록 구성하기 바랍니다.)


    추적 모니터링 컴포넌트

    FireDAC에서는 추적 모니터링 기능을 아래 3종류의 컴포넌트로 제공합니다.

    • TFDMoniFlatFileClientLink : 추적 결과를 텍스트 파일로 기록합니다. 애플리케이션이 완료되면 생성된 추적기록 파일 목록이 표시됩니다.
    • TFDMoniRemoteClientLink : 추적 결과를 FDMonitor 유틸리티에 출력(원격지 가능)합니다.(추적 시작 전에 FDMonitor를 미리 실행해야 추적이 기록됩니다.)
    • TFDMoniCustomClientLik : 추적 결과를 커스텀 이벤트핸들러를 통해 출력합니다. 애플리케이션에서는 OnOut 이벤트를 이용해 직접 추적 결과를 기록해야 합니다.
    추적 모니터링 컴포넌트는 아래와 같이 사용합니다.
    1. 추적 모니터링 컴포넌트(TFDMoniXXXXClientLink)를 폼(또는 데이터모듈)에 추가합니다.
    2. 추가한 컴포넌트의 Tracing 속성을 True로 설정(기록을 위한 속성 추가설정)
    3. 연결 컴포넌트(TFDConnection)의 연결속성에서 MonitorBy 항목을 선택(FlatFile, Remote, Custom) 합니다.

    추적 항목 선택

    추적 항목은 추적 모니터링 컴포넌트의 EventKinds 속성을 통해 선택할 수 있습니다. 각 항목은 아래와 같습니다.(참고 : Debugging and Reporting Environment Questions (FireDAC))

    • LiveCycle : 객체의 생성 / 소멸. 예를 들어, IFDPhysConnection가 생성됩니다. 
    • Error : DBMS 오류 
    • ConnConnect : 연결 열기 및 닫기 
    • ConnTransact : 시작 / 커밋 / 롤백 
    • ConnService : 특별 이벤트 
    • CmdPrepare : IFDPhysCommand.Prepare 호출 
    • CmdExecute : IFDPhysCommand.Execute 또는 Open 호출 
    • CmdDataIn : 명령 매개 변수 값 
    • CmdDataOut : 결과 집합 행 
    • AdaptUpdat :​​ 업데이트 후 처리 모든 정보 
    • Vendor : 낮은 수준 DBMS API 호출 
    • Component : 고레벨 이벤트

    추적과 모니터링에 대해 더 자세한 내용은 FireDAC 기술문서 - Tracing and Monitoring(FireDAC)을 참고하기 바랍니다.

    메타데이터와 DBMS 연결정보

    FireDAC은 데이터베이스의 메타데이터를 조회할 수 있습니다.


    메타데이터 쿼리 - TFDConnection 사용

    다음과 같이 데이터베이스 오브젝트 이름 목록을 손쉽게 조회할 수 있는 메소드를 제공합니다.

    • GetCatalogNames - 카탈로그 목록 
    • GetSchemaNames - 스키마 목록 
    • GetTableNames - 테이블 및 뷰 목록 
    • GetFieldNames - 테이블 필드 목록 
    • GetKeyFieldNames - 테이블 기본 키 목록 
    • GetGeneratorNames - 발전기 / 시퀀스 목록 
    • GetPackageNames - 패키지 목록 
    • GetStoredProcNames - 저장 프로 시저 목록

    사용 예제는 아래와 같습니다.(Memo1에 테이블명 목록을 출력)

    FDConnection1.GetTableNames('Northwind', 'dbo', '', Memo1.Lines);

    메타데이터 쿼리 - TFDMetaInfoQuery 사용

    TFDMetaInfoQuery 컴포넌트는 메타데이터를 조회할 수 있는 데이터셋 컴포넌트입니다.

    연결 설정 후 MetaInfoKind 속성만 연결하면 데이터셋을 열수 있습니다.(추가 옵션으로 CatalogName, SchemaName, BaseObjectName, ObjectName 속성을 설정합니다.)

    추적과 모니터링, 메타데이터 샘플 프로그램 소개

    이 샘플 프로그램에서는 아래 기능을 확인합니다.

    • 추적 & 모니터링 기능을 확인합니다.

    • DBMS 연결정보를 메모에 출력합니다.

    • 메타데이터

      • 테이블 목록, 필드목록, 제너레이터 목록, 스토어드프로시저 목록 조회

      • TFDConnection의 메소드와 TFDMetaInfoQuery를 이용합니다.

    [샘플코드 받기 - 데브기어 github 페이지]


    추적과 모니터링 기능

    • 폼(또는 데이터 모듈)에 추적 모니터링 컴포넌트 추가
    • FDConnection1의 연결속성 중 MonitorBy 항목을 추가한 추적 모니터링 컴포넌트 종류(Remote, FlatFile, Custom)로 선택
    • 테스트 주의사항
      • 원격 모니터링(Remote)- 애플리케이션 실행 전 FDMonitor 유틸리티(Tools > FireDAC Monitor)를 먼저 실행할 것
      • 파일 모니터링(FlatFile) - 애플리케이션 종료 후 실행파일과 같은 경로의 Trace.txt 파일에 로그가 기록됨
    procedure TForm2.Button1Click(Sender: TObject);
    begin
      // 원격 모니터링
      DM.FDMoniRemoteClientLink1.Tracing := False;
      DM.FDConnection1.Params.MonitorBy := TFDMonitorBy.mbRemote;
      DM.FDMoniRemoteClientLink1.Tracing := True;
    
      DM.FDTable1.Close;
      DM.FDTable1.Open;
    end;
    
    procedure TForm2.Button2Click(Sender: TObject);
    begin
      // 파일 모니터링
      DM.FDMoniFlatFileClientLink1.Tracing := False;
      DM.FDConnection1.Params.MonitorBy := TFDMonitorBy.mbFlatFile;
      DM.FDMoniFlatFileClientLink1.FileName := TPath.Combine(TPath.GetLibraryPath, 'trace.txt');
      DM.FDMoniFlatFileClientLink1.Tracing := True;
    
      DM.FDTable1.Close;
      DM.FDTable1.Open;
    end;

    연결 정보 레포팅
    DBMS 연결에 관한 정보를 레포팅합니다. 접속정보, FireDAC 정보, 클라이언트 모듈 정보, 세션 정보를 확인할 수 있습니다.
    DM.FDConnection1.GetInfoReport(Memo1.Lines);

    FireDAC 메타데이터 제공
    연결된 DBMS의 테이블 목록, 테이블의 필드목록, 제너레이터목록, 스토어드프로시저 목록을 화면에 출력합니다.
    // TFDConnection 메타데이터 메소드 이용
    procedure TForm2.Button4Click(Sender: TObject);
    var
      MetaType: string;
    begin
      MetaType := (Sender as TButton).Caption;
      if MetaType = 'GetTableNames' then
        DM.FDConnection1.GetTableNames('', '', '', Memo2.Lines)
      else if MetaType = 'GetFieldNames' then
        DM.FDConnection1.GetFieldNames('', '', 'EMPLOYEE', '', Memo2.Lines)
      else if MetaType = 'GetGeneratorNames' then
        DM.FDConnection1.GetGeneratorNames('', '', '', Memo2.Lines)
      else if MetaType = 'GetStoredProcName' then
        DM.FDConnection1.GetStoredProcNames('', '', '', '', Memo2.Lines)
      ;
    end;
    
    // TFDMetaInfoQuery 컴포넌트 이용
    procedure TForm2.Button5Click(Sender: TObject);
    var
      MetaType: string;
    begin
      DM.FDMetaInfoQuery1.Close;
    
      MetaType := (Sender as TButton).Caption;
      if MetaType = 'GetTableNames' then
        DM.FDMetaInfoQuery1.MetaInfoKind := TFDPhysMetaInfoKind.mkTables
      else if MetaType = 'GetFieldNames' then
      begin
        DM.FDMetaInfoQuery1.MetaInfoKind := TFDPhysMetaInfoKind.mkTableFields;
        DM.FDMetaInfoQuery1.ObjectName := 'EMPLOYEE';
      end
      else if MetaType = 'GetGeneratorNames' then
        DM.FDMetaInfoQuery1.MetaInfoKind := TFDPhysMetaInfoKind.mkGenerators
      else if MetaType = 'GetStoredProcName' then
        DM.FDMetaInfoQuery1.MetaInfoKind := TFDPhysMetaInfoKind.mkProcs
      ;
    
      DM.FDMetaInfoQuery1.Open;
    end;
    

    관련링크



    저작자 표시 비영리 동일 조건 변경 허락
    신고
    크리에이티브 커먼즈 라이선스
    Creative Commons License

    험프리.김현수 험프리.김현수 FireDAC FireDAC, FireDAC Skill Sprint