행 집합에서 여러 접근자 사용
여러 접근자를 사용해야 하는 세 가지 기본 시나리오가 있습니다.
여러 개의 읽기/쓰기 행 집합. 이 시나리오에서는 기본 키가 있는 테이블이 있습니다. 기본 키를 포함하여 행의 모든 열을 읽을 수 있어야 합니다. 기본 키를 제외한 모든 열에 데이터를 쓸 수도 있습니다(기본 키 열에 쓸 수 없기 때문). 이 경우 두 개의 접근자를 설정합니다.
접근자 0에는 모든 열이 포함됩니다.
접근자 1에는 기본 키를 제외한 모든 열이 포함됩니다.
성능. 이 시나리오에서는 하나 이상의 열에 그래픽, 사운드 또는 비디오 파일과 같은 많은 양의 데이터가 있습니다. 행으로 이동할 때마다 큰 데이터 파일이 있는 열을 검색하지 않을 수 있습니다. 이렇게 하면 애플리케이션 성능이 저하되기 때문입니다.
첫 번째 접근자에 큰 데이터가 있는 열을 제외한 모든 열이 포함된 별도의 접근자를 설정할 수 있으며 이러한 열에서 데이터를 자동으로 검색합니다. 첫 번째 접근자가 자동 접근자입니다. 두 번째 접근자가 큰 데이터를 보유하는 열만 검색하지만 이 열에서 데이터를 자동으로 검색하지는 않습니다. 다른 메서드를 업데이트하거나 요청 시 큰 데이터를 가져올 수 있습니다.
접근자 0은 자동 접근자입니다. 큰 데이터가 있는 열을 제외한 모든 열을 검색합니다.
접근자 1은 자동 접근자가 아닙니다. 큰 데이터가 있는 열을 검색합니다.
자동 인수를 사용하여 접근자가 자동 접근자인지 여부를 지정합니다.
여러 ISequentialStream 열 이 시나리오에서는 데이터를 보유하는
ISequentialStream
열이 두 개 이상 있습니다. 그러나 각 접근자가 하나의ISequentialStream
데이터 스트림으로 제한됩니다. 이 문제를 해결하려면 각각 하나의ISequentialStream
포인터가 있는 여러 접근자를 설정합니다.
일반적으로 BEGIN_ACCESSOR 및 END_ACCESSOR 매크로를 사용하여 접근자를 만듭니다. db_accessor 특성을 사용할 수도 있습니다. (접근자는 다음에 자세히 설명되어 있습니다. 사용자 레코드.) 매크로 또는 특성은 접근자가 자동 접근자인지 아니면 비자동 접근자인지를 지정합니다.
자동 접근자에서 , ,
MoveLast
MoveNext
MovePrev
등의MoveFirst
메서드를 이동하고 지정된 모든 열에 대한 데이터를 자동으로 검색합니다. 접근자 0은 자동 접근자여야 합니다.비자동 접근자에서 검색은 메서드(예:
Update
,Insert
또는Fetch
Delete
)를 명시적으로 호출할 때까지 발생하지 않습니다. 위에서 설명한 시나리오에서는 모든 이동에서 모든 열을 검색하지 않을 수 있습니다. 아래와 같이 하나 이상의 열을 별도의 접근자에 배치하고 비자동 접근자로 만들 수 있습니다.
다음 예제에서는 여러 접근자를 사용하여 여러 접근자를 사용하여 SQL Server pubs 데이터베이스의 작업 테이블을 읽고 씁니다. 이 예제는 여러 접근자의 가장 일반적인 사용입니다. 위의 "여러 읽기/쓰기 행 집합" 시나리오를 참조하세요.
사용자 레코드 클래스는 다음과 같습니다. 접근자 0에는 기본 키 열(ID)만 포함되고 접근자 1에는 다른 열이 포함되어 있습니다.
class CJobs
{
public:
enum {
sizeOfDescription = 51
};
short nID;
char szDescription[ sizeOfDescription ];
short nMinLvl;
short nMaxLvl;
DWORD dwID;
DWORD dwDescription;
DWORD dwMinLvl;
DWORD dwMaxLvl;
BEGIN_ACCESSOR_MAP(CJobs, 2)
// Accessor 0 is the automatic accessor
BEGIN_ACCESSOR(0, true)
COLUMN_ENTRY_STATUS(1, nID, dwID)
END_ACCESSOR()
// Accessor 1 is the non-automatic accessor
BEGIN_ACCESSOR(1, true)
COLUMN_ENTRY_STATUS(2, szDescription, dwDescription)
COLUMN_ENTRY_STATUS(3, nMinLvl, dwMinLvl)
COLUMN_ENTRY_STATUS(4, nMaxLvl, dwMaxLvl)
END_ACCESSOR()
END_ACCESSOR_MAP()
};
주 코드는 다음과 같습니다. 호출하면 MoveNext
접근자 0을 사용하여 기본 키 열 ID에서 데이터가 자동으로 검색됩니다. 끝 부근의 메서드가 Insert
접근자 1을 사용하여 기본 키 열에 쓰지 않도록 하는 방법을 확인합니다.
int main(int argc, char* argv[])
{
// Initialize COM
::CoInitialize(NULL);
// Create instances of the data source and session
CDataSource source;
CSession session;
HRESULT hr = S_OK;
// Set initialization properties
CDBPropSet dbinit(DBPROPSET_DBINIT);
dbinit.AddProperty(DBPROP_AUTH_USERID, OLESTR("my_user_id"));
dbinit.AddProperty(DBPROP_INIT_CATALOG, OLESTR("pubs"));
dbinit.AddProperty(DBPROP_INIT_DATASOURCE, OLESTR("(local)"));
hr = source.Open("SQLOLEDB.1", &dbinit);
if (hr == S_OK)
{
hr = session.Open(source);
if (hr == S_OK)
{
// Ready to fetch/access data
CTable<CAccessor<CJobs>> jobs;
// Set properties for making the rowset a read/write cursor
CDBPropSet dbRowset(DBPROPSET_ROWSET);
dbRowset.AddProperty(DBPROP_CANFETCHBACKWARDS, true);
dbRowset.AddProperty(DBPROP_CANSCROLLBACKWARDS, true);
dbRowset.AddProperty(DBPROP_IRowsetChange, true);
dbRowset.AddProperty(DBPROP_UPDATABILITY,
DBPROPVAL_UP_INSERT | DBPROPVAL_UP_CHANGE |
DBPROPVAL_UP_DELETE);
hr = jobs.Open(session, "jobs", &dbRowset);
if (hr == S_OK)
{
// Calling MoveNext automatically retrieves ID
// (using accessor 0)
while(jobs.MoveNext() == S_OK)
printf_s("Description = %s\n", jobs.szDescription);
hr = jobs.MoveFirst();
if (hr == S_OK)
{
jobs.nID = 25;
strcpy_s(&jobs.szDescription[0],
jobs.sizeOfDescription,
"Developer");
jobs.nMinLvl = 10;
jobs.nMaxLvl = 20;
jobs.dwDescription = DBSTATUS_S_OK;
jobs.dwID = DBSTATUS_S_OK;
jobs.dwMaxLvl = DBSTATUS_S_OK;
jobs.dwMinLvl = DBSTATUS_S_OK;
// Insert method uses accessor 1
// (to avoid writing to the primary key column)
hr = jobs.Insert(1);
}
jobs.Close();
}
session.Close();
}
source.Close();
}
// Uninitialize COM
::CoUninitialize();
return 0;
}