소프트웨어/ASP

ASP Component 에서 RecordSet 으로 리턴하기

falconer 2007. 1. 10. 15:32

ASP Component 에서 RecordSet 으로 리턴하기


[요약]

보통 우리는 ADO Recordset(_Recordset)을 데이타베이스(SQL, Oracle, Access, ...)로부터 얻어서 사용한다. atl2ado.exe 나 ado2atl.exe 같은 샘플 프로그램이 모두 그런데 본 아티클에서는 Recordset 을 Database 가 아닌 수작업으로 만드는 코드를 작성해본다.


[추가정보]

1. Visual C++ 의 ATL COM AppWizard 를 이용해서 ATL 프로젝트 (manual_recordset)를 구성한다.


2. 프로젝트에 Simple Object 를 추가하고 이름을 MyObject 이라한다.


3. MyObject 에 ADO recordset 을 반환하는 메소드를 추가하기 위해 'import "helper.idl"을 추가한다.


4. 메소드를 추가하여 다음과 같은 manual_recordset.idl 을 만든다.

[ object, uuid(04611C2D-BBA6-11D2-ACF5-00C04F7A37DE), dual, helpstring("IMyObject Interface"), pointer_default(unique) ]

interface IMyObject : IDispatch

{

[id(1), helpstring("method GetRecordset")] HRESULT GetRecordset([out,retval]_Recordset **ppRecordset);

};... 


5. helper.idl 파일을 프로젝트에 추가한다.

import "oaidl.idl";
import "ocidl.idl";
import "helper.idl";
import "msado15.idl";


6. helper.h 를 프로젝트에 추가한다.
#ifndef HELPER_H
#define HELPER_H
 struct _Recordset;
 #if !defined(__cplusplus) || defined(CINTERFACE)
  typedef struct _Recordset _Recordset;
#endif
#endif


7. 다음과 같이 메소드를 구현한다. 
STDMETHODIMP CMyObject::GetRecordset(_Recordset **ppRecordset)
{
 // TODO: Add your implementation code here
 HRESULT hr = m_recordset.CreateInstance(__uuidof(Recordset));
 m_recordset->PutCursorLocation(adUseClient);
 m_recordset->Fields->Append("dbkey", adInteger,adEmpty,adFldUnspecified);
 m_recordset->Fields->Append("field1", adVarChar,40,adFldIsNullable);
 m_recordset->Fields->Append("field2", adVarChar,40,adFldUnspecified);
 m_recordset->Open(vtMissing,vtMissing,adOpenStatic,adLockBatchOptimistic ,-1);
 //////////////////////////////////////////
 // Column name safearray VARIANT varClmNames;
 VariantInit(&varClmNames);
 varClmNames.vt = VT_ARRAY | VT_VARIANT;
 SAFEARRAY* psaCol;
 SAFEARRAYBOUND bounds = {3,0};
 psaCol = SafeArrayCreate(VT_VARIANT, 1, &bounds);
 VARIANT* ptrVariant;
 SafeArrayAccessData(psaCol, (void**)&ptrVariant);
 ptrVariant[0].vt = VT_BSTR;
 ptrVariant[0].bstrVal = SysAllocString(L"dbKey");
 ptrVariant[1].vt = VT_BSTR;
 ptrVariant[1].bstrVal = SysAllocString(L"field1");
 ptrVariant[2].vt = VT_BSTR;
 ptrVariant[2].bstrVal = SysAllocString(L"field2");
 SafeArrayUnaccessData(psaCol);
 varClmNames.parray = psaCol;
 ////////////////////////////////////////////////
 // Data Safearray VARIANT varData;
 VariantInit(&varData);
 varData.vt = VT_ARRAY | VT_VARIANT;
 SAFEARRAY* psaData;
 psaData = SafeArrayCreate(VT_VARIANT, 1, &bounds);
 SafeArrayAccessData(psaData, (void**)&ptrVariant);
 ptrVariant[0].vt = VT_BSTR;
 ptrVariant[0].bstrVal = SysAllocString(L"1");
 ptrVariant[1].vt = VT_BSTR;
 ptrVariant[1].bstrVal = SysAllocString(L"field1-value1");
 ptrVariant[2].vt = VT_BSTR;
 ptrVariant[2].bstrVal = SysAllocString(L"field2-value1");
 SafeArrayUnaccessData(psaData);
 varData.parray = psaData;
 ////////////////////////////////////////////////////
 m_recordset->AddNew(varClmNames,varData);
 ////////////////////////////////////////////////
 // Data Safearray VariantInit(&varData);
 varData.vt = VT_ARRAY | VT_VARIANT;
 psaData = SafeArrayCreate(VT_VARIANT, 1, &bounds);
 SafeArrayAccessData(psaData, (void**)&ptrVariant);
 ptrVariant[0].vt = VT_BSTR;
 ptrVariant[0].bstrVal = SysAllocString(L"2");
 ptrVariant[1].vt = VT_BSTR;
 ptrVariant[1].bstrVal = SysAllocString(L"field1-value2");
 ptrVariant[2].vt = VT_BSTR;
 ptrVariant[2].bstrVal = SysAllocString(L"field2-value2");
 SafeArrayUnaccessData(psaData);
 varData.parray = psaData;
 ////////////////////////////////////////////////////
 m_recordset->AddNew(varClmNames,varData);
 *ppRecordset = m_recordset;
 m_recordset->AddRef();
 return S_OK;


출처 : wunderbar