|
평소 C++빌더포럼의 도움말 덕에 빌더 프로그램밍에 많은 도움을 받고 있습니다.
오늘은 제가 알아낸 보잘 것 없는 팁을 하나 소개하여 고마움을 표하고자 합니다.
유니코드 utf8 코드 포맷을 사용하는 DB 관련 유틸리티를 작성하면서 많은 애로를 겪었지만
이제는 제가 필요로 하는 지식들은 거의 다 습득한 상태입니다. 그 중에서도 CLOB 데이타의
읽기와 쓰기가 가장 까다로왔습니다. 포럼의 BLOB 관련 글을 참고하거나 TNTUNICODE 콘트롤의
TNTDBRICHEDIT를 사용해 보아도 CLOB 데이터를 완전히 읽거나 쓸 수 없습니다.
다음 소개하는 코드들은 비록 난삽하지만 제가 충분히 검증한 것이므로 동작에 이상이 없는 것입니다.
BlobField을 이용한 Clob 데이터처리도 그동안 무수히 실패해서 Oracle Database Acces 콘트롤을 이용하는
방법을 소개하도록 하겠습니다.
여기서 한가지 유념해 둘 것은 DB의 코드 포맷은 utf8 유니코드이고 클라이언트에서는 utf16 유니코드(정확히 말하면 MS의 USC2 유니코드)인 점입니다.
// CLOB 데이터의 읽기
void __fastcall TFormAA25::GetDataFromQuerySet(TOraQuery *OraQuery1,AnsiString CurIdStr)
{
TTntListItem *NI;
*** TOraLob *CurClob;
*** WideString Wstr, Wstr2;
wchar_t wstr[100000],wstr2[100000];
AnsiString Kstr;
int i, count;
AnsiString FieldName;
WideString WFieldName;
int FieldType;
GetRecordFromQuerySet(OraQuery1,CurIdStr);
count=OraQuery1->FieldDefs->Count;
TntRichEdit1->Lines->Clear();
TntListView1->Items->Clear();
NI=TntListView1->Items->Add();
for(i=0;i<count;i++){
FieldName=OraQuery1->FieldDefs->Items[i]->Name;
FieldType=OraQuery1->FieldDefs->Items[i]->DataType;
if(i==0) NI->Caption=(WideString)FieldName;
else NI->SubItems->Add((WideString)FieldName);
}
NI=TntListView1->Items->Add();
for(i=0;i<count;i++){
FieldName=OraQuery1->FieldDefs->Items[i]->Name;
FieldType=OraQuery1->FieldDefs->Items[i]->DataType;
if(OraQuery1->Fields->Fields[i]->Size==0){
if(FieldType==31){
CurIdStr=(AnsiString)OraQuery1->Fields->Fields[0]->Value;
TntRichEdit1->Visible=true;
**** CurClob=OraQuery1->GetLob(FieldName);
**** Wstr=CurClob->AsWideString;
TntRichEdit1->Lines->Add(Wstr);
//NI->SubItems->Add((WideString)"CLOB");
}
else{
//WFieldName=(WideString)"NULL";
//NI->SubItems->Add((WideString)WFieldName);
}
}
else{
//WFieldName=(WideString)OraQuery1->Fields->Fields[i]->Value;
if(i==0){
//NI->Caption=WFieldName;
}
else{
// NI->SubItems->Add((WideString)WFieldName);
}
}
}
}
// Clob 데이터의 업데이트 쓰기
void __fastcall TFormAA25::InputDataIntoQuerySet(TOraQuery *OraQuery1)
{
WideString Wstr;
AnsiString Sql="INSERT INTO AA25_TAB(AA20_NO,AA10_NO,AA15_NO, AA25_XMLCONTENTS) VALUES (:aa20no, :aa10no,:aa15no, EMPTY_CLOB()) RETURNING AA25_XMLCONTENTS INTO :AA25_XMLCONTENTS";
if(OraQuery1->Active==true) OraQuery1->Active=false;
OraQuery1->SQL->Clear();
OraQuery1->SQL->Add(Sql);
OraQuery1->ParamByName("aa20no")->AsString="20253_009_0026";
OraQuery1->ParamByName("aa10no")->AsString="kh2_je_a_vsu_20253_009";
OraQuery1->ParamByName("aa15no")->AsString="009";
**** TOraLob *vBLOB;
**** vBLOB = new TOraLob(OraSession1->OCISvcCtx);
**** vBLOB->CreateTemporary(ltClob);
**** vBLOB->IsUnicode=true;
Wstr=TntRichEdit1->Lines->Text;
vBLOB->AsWideString=Wstr;
**** vBLOB->WriteLob();
OraQuery1->ParamByName("AA25_XMLCONTENTS")->DataType= ftOraClob;
OraQuery1->ParamByName("AA25_XMLCONTENTS")->ParamType=ptInput ;
OraQuery1->ParamByName("AA25_XMLCONTENTS")->AsOraClob->IsUnicode=true;
**** OraQuery1->ParamByName("AA25_XMLCONTENTS")->AsOraClob=vBLOB;
OraQuery1->ExecSQL();
delete vBLOB;
}
위의 두 코드에서 *****로 표시한 부분을 잘 보아 주시기 바랍니다.
그리고 TTntListItem, TTntRichEdit 등은 유니코드를 처리하기 위한 것으로
안시스트링이라면 TListItem, TRichEdit를 사용하시면 됩니다.
|