Aracılığıyla paylaş


Satır Kümesinde Çoklu Erişimci Kullanma

Birden fazla erişimcileri kullanmaya ihtiyaç duyduğunuz üç temel senaryo var:

  • Birden fazla okuma/yazma satır kümesi. Bu senaryoda, birincil anahtarlı bir tablo vardır. Birincil anahtar dahil satırdaki tüm sütunları okuyabilmeyi isteyin. Ayrıca, birincil anahtar dışındaki tüm sütunlara veri yazabilmek istersiniz (çünkü birincil anahtar sütununa yazamazsınız). Bu durumda iki erişimci ayarlayın:

    • Erişimci 0 tüm sütunları içerir.

    • Erişimci 1, birincil anahtar dışındaki tüm sütunları içerir.

  • Performans. Bu senaryoda, bir veya daha fazla sütun yüksek miktarda veri içerir örneğin, grafikler, ses veya video dosyaları. Bir satıra taşıdığınızda, muhtemelen sütunu geniş veri dosyası ile almayı istemezsiniz, çünkü bu şekilde hareket etmek uygulamanızın performansını azaltır.

    İlk erişimcinin büyük verilere sahip olanlar dışında tüm sütunları içerdiği ve otomatik olarak bu sütunlardan veri aldığı ayrı erişimciler ayarlayabilirsiniz; İkinci erişimci yalnızca büyük veri içeren sütunları alır ancak verileri bu sütundan otomatik olarak almaz. Diğer yöntemlerin büyük verileri isteğe bağlı olarak güncelleştirmesini veya getirmesini sağlayabilirsiniz.

    • Erişimci 0 otomatik bir erişimcidir; büyük verileri içeren hariç tüm sütunları alır.

    • Erişimci 1 otomatik bir erişimci değildir; büyük verileri içeren sütunu alır.

    Erişenin otomatik bir erişen olup olmadığını belirtmek için otomatik bağımsız değişkeni kullanın.

  • Birden fazla ISequentialStream sütunu. Bu senaryoda, ISequentialStream verileri içeren birden fazla sütun bulunur. Ancak, her erişen bir ISequentialStream veri akışı ile sınırlıdır. Bu sorunu çözmek için her biri bir ISequentialStream işaretçisi kullanan birkaç erişimci kurun.

Normalde erişimcileri BEGIN_ACCESSOR ve end_accessor makrolarını kullanarak oluşturursunuz. Ayrıca, db_accessor özniteliğini kullanabilirsiniz. (Erişimciler, Kullanıcı Kayıtları bağlantısında daha ayrıntılı olarak açıklanmıştır.) Makrolar veya öznitelik bir erişimcinin otomatik bir erişimci mi yoksa otomatik olmayan bir erişimci mi olduğunu belirtir:

  • Otomatik erişende MoveFirst, MoveLast, MoveNext ve MovePrev gibi taşıma yöntemleri belirtilen sütunlar için otomatik olarak veri geri alır. Erişimci 0 otomatik erişimci olmalıdır.

  • Bir otomatik olmayan erişimcide açıkça Update, Insert, Fetch veya Delete gibi bir yöntem çağırmadıkça alma gerçekleşmez. Yukarıda açıklanan senaryolarda her taşımada kolonların tümünü almak istemeyebilirsiniz. Ayrı bir erişimciye bir veya birden fazla sütun yerleştirebilir ve bu sütunu aşağıda gösterildiği gibi otomatik olmayan bir erişimci haline getirebilirsiniz.

Aşağıdaki örnek çoklu erişimciler kullanan SQL Sunucu pubs veritabanının işler tablosuna okumak ve yazmak için çoklu erişimciler kullanır. Çoklu erişimcilerin en yaygın kullanımı budur; bkz: yukarıdaki "çoklu okuma/yazma satır kümeleri" senaryosu.

Kullanıcı kayıt sınıfı aşağıdaki gibidir. İki erişimci ayarlar: erişimci 0 yalnızca birincil anahtar sütununu (ID) içerir ve erişimci 1 diğer sütunları içerir.

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()
};

Ana kod aşağıdaki gibidir: MoveNext öğesini çağırmak, verileri erişimci 0'ı kullanan birincil anahtar sütunu kimliğinden otomatik olarak alır. Sona yakın Ekle yönteminin birincil anahtar sütununa yazmayı engellemek üzere erişen 1'i nasıl kullandığına dikkat edin.

int main(int argc, char* argv[])
{
    // Initalize 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;
}

Ayrıca bkz.

Kavramlar

Erişimcileri Kullanma

Kullanıcı Kayıtları