다음을 통해 공유


행 집합에서 여러 접근자 사용

여러 접근자를 사용해야 하는 세 가지 기본 시나리오가 있습니다.

  • 여러 개의 읽기/쓰기 행 집합. 이 시나리오에서는 기본 키가 있는 테이블이 있습니다. 기본 키를 포함하여 행의 모든 열을 읽을 수 있어야 합니다. 기본 키를 제외한 모든 열에 데이터를 쓸 수도 있습니다(기본 키 열에 쓸 수 없기 때문). 이 경우 두 개의 접근자를 설정합니다.

    • 접근자 0에는 모든 열이 포함됩니다.

    • 접근자 1에는 기본 키를 제외한 모든 열이 포함됩니다.

  • 성능. 이 시나리오에서는 하나 이상의 열에 그래픽, 사운드 또는 비디오 파일과 같은 많은 양의 데이터가 있습니다. 행으로 이동할 때마다 큰 데이터 파일이 있는 열을 검색하지 않을 수 있습니다. 이렇게 하면 애플리케이션 성능이 저하되기 때문입니다.

    첫 번째 접근자에 큰 데이터가 있는 열을 제외한 모든 열이 포함된 별도의 접근자를 설정할 수 있으며 이러한 열에서 데이터를 자동으로 검색합니다. 첫 번째 접근자가 자동 접근자입니다. 두 번째 접근자가 큰 데이터를 보유하는 열만 검색하지만 이 열에서 데이터를 자동으로 검색하지는 않습니다. 다른 메서드를 업데이트하거나 요청 시 큰 데이터를 가져올 수 있습니다.

    • 접근자 0은 자동 접근자입니다. 큰 데이터가 있는 열을 제외한 모든 열을 검색합니다.

    • 접근자 1은 자동 접근자가 아닙니다. 큰 데이터가 있는 열을 검색합니다.

    자동 인수를 사용하여 접근자가 자동 접근자인지 여부를 지정합니다.

  • 여러 ISequentialStream 열 이 시나리오에서는 데이터를 보유하는 ISequentialStream 열이 두 개 이상 있습니다. 그러나 각 접근자가 하나의 ISequentialStream 데이터 스트림으로 제한됩니다. 이 문제를 해결하려면 각각 하나의 ISequentialStream 포인터가 있는 여러 접근자를 설정합니다.

일반적으로 BEGIN_ACCESSOR 및 END_ACCESSOR 매크로를 사용하여 접근자를 만듭니다. db_accessor 특성을 사용할 수도 있습니다. (접근자는 다음에 자세히 설명되어 있습니다. 사용자 레코드.) 매크로 또는 특성은 접근자가 자동 접근자인지 아니면 비자동 접근자인지를 지정합니다.

  • 자동 접근자에서 , , MoveLastMoveNextMovePrev 등의 MoveFirst메서드를 이동하고 지정된 모든 열에 대한 데이터를 자동으로 검색합니다. 접근자 0은 자동 접근자여야 합니다.

  • 비자동 접근자에서 검색은 메서드(예: Update, Insert또는 FetchDelete)를 명시적으로 호출할 때까지 발생하지 않습니다. 위에서 설명한 시나리오에서는 모든 이동에서 모든 열을 검색하지 않을 수 있습니다. 아래와 같이 하나 이상의 열을 별도의 접근자에 배치하고 비자동 접근자로 만들 수 있습니다.

다음 예제에서는 여러 접근자를 사용하여 여러 접근자를 사용하여 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;
}

참고 항목

접근자 사용
사용자 레코드