다음 링크의 파일을 다운로드 받아 압축해재 후 사용하시기 바랍니다.(7zip 등의 압축프로그램을 이용해 압축해제 해보세요.)
32bit
http://opensource.spotify.com/cefbuilds/cef_binary_3.3626.1886.g162fdec_windows32.tar.bz2
64bit
http://opensource.spotify.com/cefbuilds/cef_binary_3.3626.1886.g162fdec_windows64.tar.bz2
The method signature must be generated by taking the query string, and creating a HMAC-SHA256 signature using your API key as the secret key. (메소드 시그니처는 쿼리 스트링을 가져와 API Key를 시크릿 키로 HMAC-SHA256 시그니처를 생성해야 한다.)
위에서 API 키는 서비스 등록시 발급받은 값입니다.
쿼리 스트링은 URL 중 "?" 뒤의 문자열입니다. 예를 들면
Customers?customerCode=ACME 중 customerCode=ACME가 쿼리 스트링입니다.
HMAC-SHA256은 다음과 같이 구현할 수 있습니다.
HMAC-SHA256
다음 샘플은 쿼리스트링(ProductCode=XXX)와 API Key(UNLEASHED_API_KEY: 상수)를 이용해 HMAC을 SHA256으로 시그니처를 생성해 HTTP 해더에 추가하는 내용입니다.
이 글에서는 OAuth 2.0을 이용해 카카오 API와 연동하는 방법을 델파이를 통해 알아봅니다.
이 글을 통해 카카오톡 프로필 정보와 사진을 델파이 애플리케이션에서 불러오는 예제를 작성할 수 있습니다.
OAuth 2.0
API(또는 서비스) 이용 시 인증(Authentication)과 리소스(제공 서비스)에 대한 권한부여(Authorization)는 필수사항입니다. 인증과 권한부여의 대표적인 방법 중 하나가 OAuth입니다.
OAuth는 서버와 클라이언트 사이에 인증을 완료 시 권한부여의 결과로 엑세스 토큰(Access Token)을 발급하고, 이 엑세스 토큰을 이용해 클라이언트는 API(또는 서비스)에 접근 및 서비스를 요청하게 됩니다. 서버는 엑세스 토큰 기반으로 서비스와 권한에 대한 접근 여부를 판단해 데이터를 제공합니다.
OAuth는 현재 2.0 버전을 제공하며, 카카오, 구글, 페이스북에서 OAuth 2.0을 통해 서비스에 대한 인증 및 권한부여를 사용하고 있습니다.
OAuth 2.0에 대한 내용은 자세한 내용은 이 글의 하단 "관련/참고 링크"를 통해 알아볼 수 있습니다.
OAuth 2.0 사용 시 API 인증 흐름
다음 그림은 카카오 API 서비스에 접근하기 위해 OAuth 2.0 인증의 흐름을 7 단계로 나타냅니다.
0, 카카오 서비스를 이용하려면 사전에 앱을 등록 후 앱의 API 키를 발급받아야 합니다.
1, 카카오 서비스에 접근하기 위해 카카오 로그인 페이지를 웹브라우저에 표시합니다.
2, 사용자는 로그인 페이지에 ID, 비밀번호를 입력해 인증을 요청합니다.
3, 카카오 인증서버는 사용자를 인증하고 사용자 인증완료 페이지로 리다이렉션합니다. 이때 인증 코드를 함께 전달합니다.
(해당 내용은 모든 데이터셋(TDataSet을 상속받은 컴포넌트) 즉, FireDAC, dbExpress, dbGo(ADO) 등에 적용할 수 있습니다.)
대부분의 DBMS에서 Blob(Binary Large object) 타입의 컬럼을 만들 수 있습니다. 이 컬럼에는 이미지등의 큰 바이너리 데이터를 취급할 수 있습니다.
아래 코드는 Blob 컬럼에서 이미지를 읽고, 쓰는 델파이 예제입니다.
Blob 컬럼에 이미지 데이트 쓰기
var
wic: TWICImage; // Microsoft Windows Imaging Component
Stream: TMemoryStream;
begin
Stream := TMemoryStream.Create;
try
Image1.Picture.SaveToStream(Stream);
qryPhoto.Edit; // 데이터셋 수정
(qryPhoto.FieldByName('PHOTO_PHOTO') as TBlobField).LoadFromStream(Stream);
qryPhoto.Post;
finally
Stream.Free;
end;
end;
Blob 컬럼에서 이미지 데이터 읽기
var
wic: TWICImage; // Microsoft Windows Imaging Component
Stream: TMemoryStream;
begin
Stream := TMemoryStream.Create;
wic := TWICImage.Create;
try
(qryPhoto.FieldByName('PHOTO_FIELD') as TBlobField).SaveToStream(Stream);
if Stream.Size > 0 then
begin
try
wic.LoadFromStream(Stream);
Image1.Picture.Assign(wic);
except
end;
end;
finally
Stream.Free;
wic.Free;
end;
end;
지정된 데이터셋의 레코드의 기본 키를 취득하고 그것과 같은 기본 키 대응 레코드를 원 데이터셋에서 찾습니다. 그 후 다음 중 하나를 수행합니다.
이 데이터셋의 레코드에 해당하는 레코드가 지정된 데이터셋에있는 경우, 해당 레코드에서이 데이터셋의 레코드를 업데이트합니다.
지정된 데이터셋의 레코드에 해당하는 레코드가이 데이터셋에 없는 경우는 지정된 데이터셋의 레코드가 새 레코드로이 데이터셋에 추가됩니다.
해당 레코드가 삭제 된 레코드가 있으면 그것을 삭제합니다.
예
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)를 데이터셋을 병합합니다.
작성하며 주의할 점은,
병합해 넣을 데이터셋(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;
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
이 글에서는 웨비나 다시보기와 함께 웨비나 일부 내용을 샘플코드와 함께 소개합니다. 하단 온라인 기술 도움말 링크를 통해 더 자세한 내용을 추가학습하시기 바랍니다.
1회차에서는 FireDAC을 소개하고 연결하는 과정으로 진행합니다.
FireDAC 소개
FireDAC은 델파이와 C++빌더에서 멀티-디바이스 데이터베이스 애플리케이션을 개발할 수 있는 범용(Universal) 데이터 엑세스 컴포넌트입니다.
FireDAC은 통합 API를 사용해 다양한 데이터베이스를 동일한 코드로 제어할 수 있습니다. 그렇기 때문에 개발자는 데이터베이스를 신경쓰지 않고 애플리케이션 개발에 집중할 수 있고, DBMS 변경 시 대부분의 코드를 재사용할 수 있습니다. 그 뿐아니라 FireDAC은 데이터베이스 별 고유기능을 사용하고, 최적의 성능을 발휘할 수 있도록 데이터베이스 별 네이티브 드라이버를 지원합니다.
또한 기술적으로 아래의 장점을 제공합니다.
30배 빠른 데이터 입력이 가능한 Array DML
DBMS의 사용내역을 추적하고 모니터링
엑셀형식으로 내보내고, 가져오기 기능을 개발할 수 있는 Batch Move
DB에서 가져온 메모리상의 데이터를 대상으로 쿼리할 수 있는 Local SQL
이 외의 기술적인 장점은 아래의 FireDAC Skill Sprints 동영상과 샘플로 고급기능 활용하기 시리즈로 직접 확인하시기 바랍니다.
FireDAC 추적기능을 이용하면 애플리케이션과 데이터베이스 사이의 통신내용을 상세하게 보거나 기록할 수 있습니다. 이 추적 정보에는 이벤트 발생시간, API 호출내역, DB로 전송된 SQL 문, 파라메터와 필드 값, 오류와 경고 등이 기록되어 여러분의 DB 애플리케이션의 문제점을 디버깅하고 해결하는데 유용하게 사용할 수 있습니다.
샘플에서는 데이터 조회(테이블 오픈) 시 애플리케이션과 DBMS의 통신내용을 모니터링 유틸리티(FireDAC Monitor)로 확인하고, DB 애플리케이션 디버깅 시 유용한 메터데이터(DBMS 객체 정보)를 이용해 테이블, 필드, 제너레이터, 스토어드 프로시저 목록을 조회해 봅니다.
캐쉬 업데이트는 애플리케이션의 메모리 영역(즉, 데이터셋)에 업데이트 내역을 기록하고, DBMS에 한번에 업데이트(또는 일괄취소) 할 수 있는 기능입니다.
캐쉬 업데이트를 사용하면 작업내용을 로컬에서 관리하므로 DBMS와의 트래픽을 줄일 수 있고, 사용자는 통신속도와 관계없이 빠른 작업이 가능합니다. 그리고 작업이력을 확인(변경된 레코드 조회, 변경된 항목의 이전 값 확인 등)하고, 작업 변경취소(마지막 작업 변경취소, 선택한 레코드 변경취소 등)을 FireDAC에서 제공하는 메소드를 이용해 손쉽게 구현할 수 있습니다.
샘플에서는 캐쉬 업데이트를 이용해 조회한 데이터를 메모리 상에서 편집(입력, 수정, 삭제) 후 업데이트 목록 표시, 변경취소, 일괄적용/취소 기능을 구현해 봅니다.
이 글에서는 웨비나 다시보기와 함께 웨비나 일부 내용을 샘플코드와 함께 소개합니다. 하단 온라인 기술 도움말 링크를 통해 더 자세한 내용을 추가학습하시기 바랍니다.
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 ).
데이터 편집 허용 ( 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 도 영향을줍니다.
데이터가 많은 경우 전체 데이터를 가져와 화면에 표시하는 것 보다 부분적으로 표시하고 추가로 데이터를 표시하는 것이 효과적일 수 있습니다.
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 컴포넌트로 구현할 수 있습니다.
Array DML은 실행에 필요한 매개변수(Parameters) 배열을 이용한 한번에 DBMS 명령을 실행하는 기능입니다. 이 방법은 DBMS와 애플리케이션 사이의 통신비용을 줄이고 DBMS 명령 요청을 줄입니다. 그 결과 실행 속도가 향상됩니다.
다음 그림에서 이 프로세스를 보여줍니다.
동영상을 보셨다면 아시겠지만 1만건의 데이터를 DBMS에 입력 시
트랜젝션으로 작업을 묶어주면 20배 빨라지고,
Array DML을 사용하면 다시 10배가 더 빨라진다고 설명합니다.
Array DML의 사용법 예시입니다.
with FDQuery1 do begin
SQL.Text := 'insert into Customers (ID, RegionID, Name, Note) values (:ID, :RegionID, :Name, :Note)';
// Set up parameter types
Params[0].DataType := ftInteger;
Params[1].DataType := ftInteger;
Params[2].DataType := ftString;
Params[2].Size := 40;
Params[3].DataSize := ftMemo;
// Set up parameters' array size
Params.ArraySize := 10000;
// Set parameter values
for i := 0 to 10000 - 1 do begin
if i mod 100 = 0 then
// force PK violation
Params[0].AsIntegers[i] := i - 1
else
Params[0].AsIntegers[i] := i;
Params[1].AsIntegers[i] := GetRegionIdForCustomer(i);
Params[2].AsStrings[i] := 'Somebody ' + IntToStr(i);
Params[3].Clear(i);
end;
// Execute batch
Execute(10000, 0);
end;
위 코드 10번째 줄에서 배열크기(Params.ArraySize)를 지정합니다.
13~20번 줄에서는 Params[0].AsStrings[i] 형태로 배열로 데이터를 입력합니다.(AsString 뒤에 s가 붙은 것을 유의하세요.)
데이터 입력 후 23번째 줄에 Execute 메소드로 실행요청을 합니다. 이때 배열의 크기를 인자로 넘겨줍니다.
이 글에서는 웨비나 다시보기와 함께 웨비나 일부 내용을 샘플코드와 함께 소개합니다. 하단 온라인 기술 도움말 링크를 통해 더 자세한 내용을 추가학습하시기 바랍니다.
3회차에서는 FireDAC의 Cached Updates와 Auto-Inc Fields에 대해 진행했습니다.
캐쉬를 이용한 업데이트
캐쉬 업데이트는 애플리케이션의 메모리 영역(즉, 데이터셋)에 업데이트 내역을 기록하고, DBMS에 한번에 업데이트하거나 일괄취소할 수 있는 기능입니다.
캐쉬 업데이트를 사용하면 작업내용을 로컬에서 관리하므로 DBMS와의 트래픽을 줄일 수 있고, 사용자는 인터넷속도와 관계없이 빠르게 작업할 수 있습니다. 그리고 부가적으로 작업이력을 확인(변경된 레코드 조회, 변경된 값 확인 등)하고, 작업을 되돌리는 기능(최종작업 되돌리기, 선택 레코드 되돌리기 등)등을 제공되는 메소드를 이용해 손쉽게 구현할 수 있습니다.
UndoLastChange - 마지막으로 수정 한 레코드로 이동하고 레코드를 이전 상태로 되돌립니다.
CancelUpdates - 변경 로그에 포함 된 모든 레코드를 취소합니다.
업데이트 적용
캐쉬의 변경을 데이터베이스에 적용하려면 ApplyUpdates 메소드를 사용합니다. 레코드 적용 시 예외가 발생한 경우 그 예외는 레코드에 연결됩니다.
ApplyUpdates 메소드는 다음 특징이 있습니다.
ApplyUpdates 시 예외를 발생하지 않고 리턴값으로 예외 수 반환
트랜젝션으로 업데이트가 적용되지 않는다. 애플리케이션에서 ApplyUpdates로 적용해야 한다.
즉시 업데이트와 데이터셋 처리 방식은 동일하다.
업데이트 이후 수정 된 레코드는 변경 로그가 남아 있어, 변경로그를 삭제하려면 CommitUpdates 메소드를 호출해야 합니다.
FDQuery1.Append;
...
FDQuery1.Post;
FDConnection1.StartTransaction;
iErrors := FDQuery1.ApplyUpdates;
if iErrors = 0 then begin
FDQuery1.CommitUpdates;
FDConnection1.Commit;
end
else
FDConnection1.Rollback;
캐시를 이용한 업데이트에 대한 자세한 내용은 FireDAC 기술문서 - Caching_Updates를 참고하기 바랍니다.
자동 증가 필드
FireDAC은 새로운 레코드 추가 시 자동증가 컬럼에 새로운 값을 할당 할 수 있습니다.(즉시 업데이트와 캐쉬 업데이트 모두에서 동작)
DBMS의 자동 증가 필드는 다음과 같이 특수한 Identity(또는 유사한) 컬럼 데이터형식을 사용하거나 제너레이터(또는 시퀀스)와 테이블 트리거를 사용해 구현됩니다.
데이터베이스와 연결된 상태에서 데이터셋(TFDQuery, TFDTable)에서 필드를 추가합니다.
(모든 필드 추가 : 데이터셋 컴포넌트 > 우측 마우스 메뉴 > Fields Editor > 우측 마우스 > Add all fields)
자동 증가 컬럼(SEQ) 선택 후 AutoGenerateValue 속성을 arAutoInc로 설정합니다.
코드로 진행 시 아래와 같습니다.
SEQ(자동증가 컬럼) 선택 후 AutoGenerateValue 속성을 arAutoInc로 설정합니다. 아래의 코드로 설정 가능합니다.
procedure TDM.DataModuleCreate(Sender: TObject);
begin
// Auto-Inc 설정
FDQuery1SEQ.AutoGenerateValue := arAutoInc;
FDQuery1SEQ.Required := False;
FDQuery1SEQ.ReadOnly := True;
// CachedUpdates 설정
FDQuery1.CachedUpdates := True;
end;
캐쉬 업데이트 - 일괄적용 / 일괄취소
procedure TForm2.btnApplyUpdatesClick(Sender: TObject);
var
iErr: Integer;
begin
DM.FDConnection1.StartTransaction;
// ApplyUpdates는 오류를 발생하지 않음
iErr := DM.FDQuery1.ApplyUpdates(-1);
if iErr = 0 then
begin
DM.FDQuery1.CommitUpdates; // 변경로그 지우기
DM.FDConnection1.Commit;
end
else
DM.FDConnection1.Rollback;
DM.FDQuery1.Refresh;
end;
procedure TForm2.btnCancelUpdatesClick(Sender: TObject);
begin
DM.FDQuery1.CancelUpdates;
DM.FDQuery1.Refresh;
end;
캐쉬 업데이트 - 업데이트 이력 추적
// 캐쉬 보기
if DM.FDQuery1.Active then
begin
DM.FDMemTable1.CloneCursor(DM.FDQuery1, True);
DM.FDMemTable1.FilterChanges := [rtModified, rtInserted, rtDeleted];
end;
// 이전 값 확인
ShowMessage(format('이전 값: %s -> 새로운 값: %s', [
DM.FDQuery1.FieldByName('FIELD1').OldValue,
DM.FDQuery1.FieldByName('FIELD1').Value]));
// 마지막 변경 취소
DM.FDQuery1.UndoLastChange(True);
// 선택 레코드 변경 취소
DM.FDQuery1.RevertRecord;
// 저장점 생성
FSavePoint := DM.FDQuery1.SavePoint;
// 저장점으로 되돌리기
if FSavePoint > 0 then
DM.FDQuery1.SavePoint := FSavePoint;
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;
좋은 자료 공유 감사합니다.
비밀댓글입니다
다음 링크의 파일을 다운로드 받아 압축해재 후 사용하시기 바랍니다.(7zip 등의 압축프로그램을 이용해 압축해제 해보세요.)
32bit
http://opensource.spotify.com/cefbuilds/cef_binary_3.3626.1886.g162fdec_windows32.tar.bz2
64bit
http://opensource.spotify.com/cefbuilds/cef_binary_3.3626.1886.g162fdec_windows64.tar.bz2