استخدام موصلات متعددة على مجموعة الصفوف

هناك ثلاثة سيناريوهات أساسية التي تحتاج فيها إستخدام موصلات (accessors) متعددة:

  • مجموعات صفوف متعددة للقراءة/الكتابة . في هذا السيناريو، لديك جدول ذى مفتاح أساسي. تريد أن تتمكن من قراءة كافة الأعمدة في الصف, بما في ذلك المفتاح الأساسي. تحتاج أيضاً إلى أن تتمكن من كتابة بيانات إلى كافة الأعمدة باستثناء المفتاح الأساسي (لأنه لا يمكنك الكتابة إلى عمود المفتاح الأساسي). في هذه الحالة، يمكنك تعيين اثنين من الـ accessors :

    • Accessor 0 يحتوي على كافة الأعمدة .

    • Accessor 1 يحتوي على كافة الأعمدة باستثناء المفتاح الأساسي.

  • الأداء في هذا السيناريو، يحتوي عمود واحد أو أكثر على كمية كبيرة من البيانات ، على سبيل المثال , ملفات رسومات , صوت , أو فيديو. كل مرة تنتقل فيها إلى صف, غالباً لا تريد استرداد العمود ذى ملف البيانات الكبير, لأن القيام بذلك قد يبطئ أداء التطبيق الخاص بك.

    يمكنك إعداد accessors منفصلة التي يحتوي فيها الـaccessor الأول على كافة الأعمدة باستثناء تلك ذات البيانات الكبيرة , وهو يقوم باسترداد البيانات من هذه الأعمدة تلقائياً; هذا هو الـaccessor التلقائي. الـaccessor الثاني يسترد فقط العمود الذي يحتوي على بيانات كبيرة ، ولكن لا يقوم باسترداد البيانات من هذا العمود تلقائياً. يمكن أن يكون لديك أساليب أخرى تقوم بتحديث أو إحضار البيانات الكبيرة حسب الطلب.

    • Accessor 0 هو accessor تلقائي ; فإنه يسترد كافة الأعمدة باستثناء تلك ذات البيانات الكبيرة.

    • accessor 1 ليس accessor تلقائي; فإنه يسترد العمود ذا البيانات الكبيرة.

    استخدم الوسيطة التلقائية لتحديد ما إذا كان الـaccessor هو accessor تلقائي.

  • عواميد ISequentialStream المتعددة. في هذا السيناريو، يكون لديك أكثر من عمود يحتوي على بيانات ISequentialStream. ومع ذلك، كل accessor يقتصر على دفق بيانات ISequentialStream واحد. لحل هذه المشكلة, قم بإعداد عدة accessors , كل واحد يحتوي على مؤشر ISequentialStream واحد.

أنت عادةً تقوم بإنشاء الـaccessors باستخدام وحدات الماكرو BEGIN_ACCESSOR END_ACCESSOR . يمكنك أيضاً استخدام سمة db_accessor . (يتم وصف الـaccessors بشكل أكبر في سجلات المستخدم.) وحدات الماكرو أو السمة تقوم بتحديد ما إذا كان الـaccessor هو accessor تلقائى أم غير تلقائى :

  • في accessor تلقائي , أساليب النقل مثل MoveFirst ، MoveLast ، MoveNext ، و MovePrev تقوم باسترداد البيانات على كافة الأعمدة المحددة تلقائياً. يجب أن يكون accessor 0 هو الـ accessor التلقائى.

  • في حالة الـaccessor الغير تلقائي , لا يحدث الاسترداد حتى يتم استدعاء أسلوب مثل تحديث (Update) , إدراج (Insert) ، إحضار (Fetch) ,أو حذف (Delete) بشكل صريح. في السيناريوهات الموضحة أعلاه , قد لا تريد استرداد كافة الأعمدة في كل حركة. يمكنك وضع عمود أو أكثر فى accessor منفصل و جعل ذلك الـ accessor غير تلقائي , كما هو موضح أدناه.

يستخدم المثال التالي accessors متعددة للقراءة والكتابة فى جدول المهام فى قاعدة بيانات SQL Server pubs باستخدام accessors متعددة. هذا هو الاستخدام الأكثر شيوعاً للـaccessors المتعددة ; راجع سيناريو " مجموعات الصفوف المتعددة للقراءة/الكتابة" أعلاه.

تكون فئة سجل المستخدم كما يلي . يقوم بإعداد اثنين من الـ accessors: يحتوى accessor 0 على عمود المفتاح الأساسي (ID) وتحتوي accessor 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. لاحظ كيفية استخدام إدراج أسلوب قريب النهاية الموصل 1 لتجنب الكتابة إلى عمود المفتاح أساسي.

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

راجع أيضًا:

المبادئ

استخدام الموصلات (Accessors)

سجلات المستخدم