الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

مشكلة عند نسخ مجموعة كبيرة من السجلات أرجو المساعدة

بدأه محمـد عواد في 6 أكتوبر 2010 · 11 رد · 1,189 مشاهدة · في قسم Cross Platform GUI Libraries العام
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمة الله وبركاته

هذا الكود يقوم باستدعاء جميع السجلات الموجودة في جدول b1 في قاعدة بيانات أكسيس

وإدراج جميع السجلات في جدول له نفس الاسم والتصميم في قاعدة بيانات sqlite

وهو يعمل بصورة جيدة إذا كان عدد السجلات قليل

أما إذا زاد عدد السجلات بدرجة كبير فإن البرنامج يهنج ولا يكمل النسج

      QSqlQuery query3(QSqlDatabase::database("personal"));
    query3.exec("Delete from b1");
    QSqlQuery query(QSqlDatabase::database("web"));
    query.exec("select id,nass,part,page,hno,sora,aya,na,b1,seal from b1");
    while(query.next()) {
           QString a = query.value(0).toString();
           QString b = query.value(1).toString();
           QString c = query.value(2).toString();
           QString d = query.value(3).toString();
           QString e = query.value(4).toString();
           QString f = query.value(5).toString();
           QString g = query.value(6).toString();
           QString h = query.value(7).toString();
           QString i = query.value(8).toString();
           QString j = query.value(9).toString();
         query3.prepare("insert into b1 (id,nass,part,page,hno,sora,aya,na,b1,seal)"
                        "values (:id,:nass,:part,:page,:hno,:sora,:aya,:na,:b1,:seal)");
         query3.bindValue(":id",a);
         query3.bindValue(":nass",b);
         query3.bindValue(":part",c);
         query3.bindValue(":page",d);
         query3.bindValue(":hno",e);
         query3.bindValue(":sora",f);
         query3.bindValue(":aya",g);
         query3.bindValue(":na",h);
         query3.bindValue(":b1",i);
         query3.bindValue(":seal",j);
         query3.exec();

وقد جربت إيضا كود آخر بدون تحويل الاستدعاءات إلى المتغيرات الوسيطة هكذا

    
         query3.bindValue(":id",query.value(0));
         query3.bindValue(":nass",query.value(1));
         query3.bindValue(":part",query.value(2));
         query3.bindValue(":page",query.value(3));
         query3.bindValue(":hno",query.value(4));
         query3.bindValue(":sora",query.value(5));
         query3.bindValue(":aya",query.value(6));
         query3.bindValue(":na",query.value(7));
         query3.bindValue(":b1",query.value(8));
         query3.bindValue(":seal",query.value(9));

فكانت نفس النتيجة

فما هو الخطأ بارك الله فيكم

#2

وعليكم السلام ورحمة الله وبركاته ،

ما دام انه عمل مع سجلات بسيطة فهذا يعني ان الشفرة سليمة ، وافضل حل حتى تكشف المشكلة هو ان تستخدم المنقح Debugger ، ستجد في القائمة في اليسار خيار Debug اضغط عليه ومن ثم ضع نقطة توقف Break point على السطر التالي (يوجد مساحة فارغة قبل رقم السطر ، اضغط عليها وستجد علامة حمراء):

while(query.next()) {

اخيرا شغل المنقح ، وسيبدا البرنامج بالعمل حتى يصل الى نقطة التوقف وهنا سيتوقف . وعليك ان تختر step حتى تتبع التنفيذ خطوة خطوة وترى سبب التعليق Hang .

ووافنا بالنتيجة.

#3
SudaNix كتب:

وعليكم السلام ورحمة الله وبركاته ،

ما دام انه عمل مع سجلات بسيطة فهذا يعني ان الشفرة سليمة ، وافضل حل حتى تكشف المشكلة هو ان تستخدم المنقح Debugger ، ستجد في القائمة في اليسار خيار Debug اضغط عليه ومن ثم ضع نقطة توقف Break point على السطر التالي (يوجد مساحة فارغة قبل رقم السطر ، اضغط عليها وستجد علامة حمراء):

while(query.next()) {

اخيرا شغل المنقح ، وسيبدا البرنامج بالعمل حتى يصل الى نقطة التوقف وهنا سيتوقف . وعليك ان تختر step حتى تتبع التنفيذ خطوة خطوة وترى سبب التعليق Hang .

ووافنا بالنتيجة.

بارك الله فيك يا أستاذنا الكريم وأحسن الله إليك

تم تنفيذ المطلوب ولكن للأسف لم أفهم النتيجة لأني لم أستعمل المنقح Debugger من قبل

وقد أرفقت لك صورة من النتيجة

post-216903-039994200 1286451605_thumb.p

أكرر شكري ودعائي لك بالتوفيق

المرفقات
untitled.PNG
#4

لن تحتاج الى فهم النتيجة كاملة ، المهم هو معرفة عمل البرنامج هل يدخل في حلقة نهائية ؟ هل هناك قيمة معينة تسبب هذا التعليق ؟ ما هو آخر امر يتم تنفيذه وبعدها يتوقف البرنامج ؟ وهكذا.

كل ما عليك هو وضع نقطة التوقف في المكان الذي ترى انه مناسب لمعرفة المشكلة ، ومن ثم تكرار الضغط على اول زر step (بجوار المربع الأحمر) ، وهكذا سيبدأ البرنامج بالتنفيذ خطوة خطوة وعندما تضغط step مرة اخرى سنتقل الى السطر التالي الى ان تصل الى نهاية حلقة التكرار ، عندها سيعود الى بداية while لاختبار الشرط من جديد .

وعليك ان تلاحظ الخيار locals and watchers (موجود في الجزء الأيمن بدلا من threads) لمعرفة قيمة المتغيرات عند تنفيذ كل أمر.

في حالة لم ينجح معك ، ارسل الشفرة وملف قاعدة البيانات ان امكن.

والسلام عليكم.

#5
SudaNix كتب:

لن تحتاج الى فهم النتيجة كاملة ، المهم هو معرفة عمل البرنامج هل يدخل في حلقة نهائية ؟ هل هناك قيمة معينة تسبب هذا التعليق ؟ ما هو آخر امر يتم تنفيذه وبعدها يتوقف البرنامج ؟ وهكذا.

كل ما عليك هو وضع نقطة التوقف في المكان الذي ترى انه مناسب لمعرفة المشكلة ، ومن ثم تكرار الضغط على اول زر step (بجوار المربع الأحمر) ، وهكذا سيبدأ البرنامج بالتنفيذ خطوة خطوة وعندما تضغط step مرة اخرى سنتقل الى السطر التالي الى ان تصل الى نهاية حلقة التكرار ، عندها سيعود الى بداية while لاختبار الشرط من جديد .

وعليك ان تلاحظ الخيار locals and watchers (موجود في الجزء الأيمن بدلا من threads) لمعرفة قيمة المتغيرات عند تنفيذ كل أمر.

في حالة لم ينجح معك ، ارسل الشفرة وملف قاعدة البيانات ان امكن.

والسلام عليكم.

قمت بتنفيذ كل الخطوات لكن المشكلة الآن أن التعليق يحدث بعد نسخ ما يقارب من 250 سجلا

فهل يوجد طريقة للانتقال إلى عدد معين من تكرارات while لأن الضغط على زر 250 مرة مضروبا في عدد أسطر الحلقة شيء صعب (ابتسامة)

الأمر الآخر هو هل هناك احتمال أن يكون الأمر متعلق بالرامات وحجمها ؟

لأن معنى أن يتم تنفيذ الحلقة while عدد من المرات أن المشكلة ليست في الحلقة

فهل هذا الكلام صحيح

بالنسبة لملف الشفرة فقد أرفقت لك نسخة مصغرة من المشروع تحتوي على الشفرة فقط ولو أردت المشروع كاملا فسوف إرسله لك على الخاص بعد إذنك

وبالنسبة لقاعدة البيانات sqlite سيتم إنشاؤها عند تشغيل المشروع

أما بالنسبة للقاعدة أكسيس فسوف أحاول رفعها لأن حجمها كبير مع العلم أنها مأخوذة من برنامج المكتبة الشاملة في المسار

e-shamela\Books\Archive

فلو كانت عندك المكتبة الشاملة كفيتني مؤونة رفعها

بارك الله فيك وجعل ما تبذله في ميزان حسناتك

emptyproject.rar

#6

واجهت هذه المشكله مع SQLite أثناء قراءه عدد كبير من السجلات من قاعده بيانات PostgreSQL و تسجيلها في ملف SQLite وكان يأخذ وقت كبير جداً حتى يصل إلى السجل رقم 1000 و عند فتح قاعده البيانات SQLite في الذاكره فلا يأخذ تسجيل 10000 سجل أكثر من نصف ثانيه و هنا يوجد مشكله في I/O لذلك مازلت حتى الأن أبحث هل يوجد إعدادات يجب إعدادها عند فتح ملف SQLite أم لا يوجد

عموماً إذا لم يوجد أي إعدادات فأشك أن هناك خطأ ما في درايفر SQLite و هذا سيبقى الخيار الأخير إن لم أعثر على نتيجة أو هناك خطأ ما في إصدار مكتبه SQLite نفسها و يجب تحديثها.

هناك حل ممكن أن يعالج المشكله و هو أن تنشئ قاعده بيانات SQLite في الذاكره ثم تقوم بعمل Backup لها في ملف.

لمعرفه كيف تقوم بعمل Backup

http://www.sqlite.org/backup.html

1
forum-signature-01.gif
#7

انظر هنا:

http://www.sqlite.org/faq.html#q19

المشكلة تظهر في أن كل عملية insert في SQLite تتطلب انشاء transaction جديدة وهو ما يسبب هذا البطئ. والحل يكون في انشاء transaction واحدة لكل عمليات الإدخال .

جرب هذا الكود:

QSqlQuery query;
QSqlDatabase::database().transaction();

// هنا قم بعمليات الكتابة

QSqlDatabase::database().commit();

بالنسبة ل:

اقتباس
فهل يوجد طريقة للانتقال إلى عدد معين من تكرارات while لأن الضغط على زر 250 مرة مضروبا في عدد أسطر الحلقة شيء صعب

يمكنك الضغط على زر continue حيث سيكمل التنفيذ الى نقطة التوقف وبالتالي ستمر عليهم بسرعة . وكحل اخر يمكنك استخدام qDebug() لطباعة مخرجات توضيحية توضح عمل الشفرة . مثلا:

qDebug() << i++;  // to know how many times the loop is executed

وكذلك استخدمها لطباعة القيم التي تشك بانها تحمل قيمة Null قد تكون سبب في مشكلة.

تم تعديل هذه المشاركة بواسطة SudaNix في 8 أكتوبر 2010 في 18:57

2
#8

كنت أقرأ الحل في نفس الصفحه أخي SudaNix و جئت لأذكره فوجدتك ذكرته ...... سبقتني mad.giflaugh.gif

زياده على ما ذكره أخي SudaNix فأنك ممكن أن تغلق الخيار synchronous و لكن هم لا ينصحون به لأنه ممكن أن يتلف قاعده البيانات.

forum-signature-01.gif
#9

إضافه:

قم بتحديد قاعده البيانات ففي مثالك استخدم الأتي قبل قاعده while

QSqlDatabase::database("personal").transaction();

و بعد قاعده While ضع الأتي

QSqlDatabase::database("personal").commit();
forum-signature-01.gif
#10
SudaNix كتب:

انظر هنا:

http://www.sqlite.org/faq.html#q19

المشكلة تظهر في أن كل عملية insert في SQLite تتطلب انشاء transaction جديدة وهو ما يسبب هذا البطئ. والحل يكون في انشاء transaction واحدة لكل عمليات الإدخال .

جرب هذا الكود:

QSqlQuery query;
QSqlDatabase::database().transaction();

// هنا قم بعمليات الكتابة

QSqlDatabase::database().commit();

رائع رائع رائع

تمت العملية بنجاح وفي زمن قياسي

      void MainWindow::copy()
{
    QSqlQuery query3(QSqlDatabase::database("personal"));
    QSqlDatabase::database("personal").transaction();
    // هنا قم بعمليات الكتابة
    query3.exec("CREATE TABLE b1(id varchar(5) PRIMARY KEY,"
               "nass varchar(3000),"
               "part varchar(10),"
               "page varchar(10),"
               "sora varchar(10),"
               "aya varchar(10),"
               "na varchar(10),"
               "b1 varchar(10),"
               "seal varchar(3000))");
    query3.exec("insert into b1 values('1','الصفحة الأولى من الكتاب الأول', '1', '1','','0','0','0','aaaaaaa', 'F5740021')");

    ///****************************
    query3.exec("Delete from b1");
    //***************************/

    QSqlQuery query(QSqlDatabase::database("web"));
    query.exec("select id,nass,part,page,sora,aya,na from b14");
    while(query.next()) {
         query3.prepare("insert into b1 (id,nass,part,page,sora,aya,na)"
                        "values (:id,:nass,:part,:page,:sora,:aya,:na)");
           query3.bindValue(":id",query.value(0));
           query3.bindValue(":nass",query.value(1));
           query3.bindValue(":part",query.value(2));
           query3.bindValue(":page",query.value(3));
           query3.bindValue(":sora",query.value(4));
           query3.bindValue(":aya",query.value(5));
           query3.bindValue(":na",query.value(6));
           query3.exec();
       }
    QSqlDatabase::database("personal").commit();
    QMessageBox::about(this, tr("تم"),
                       tr("<b>"
                          "<h3><center>تمت عملية النسخ بنجاح</center></h3>"
                          "<BR>-"
                          "</b>"));
}

اقتباس

بالنسبة ل:

يمكنك الضغط على زر continue حيث سيكمل التنفيذ الى نقطة التوقف وبالتالي ستمر عليهم بسرعة . وكحل اخر يمكنك استخدام qDebug() لطباعة مخرجات توضيحية توضح عمل الشفرة . مثلا:

qDebug() << i++;  // to know how many times the loop is executed

وكذلك استخدمها لطباعة القيم التي تشك بانها تحمل قيمة Null قد تكون سبب في مشكلة.

لقد فتحت لي بابا عظيما في البرمجة سأقوم إن شاء الله في الفترة القادمة بدراسة كل شيء عن المنقح

بارك الله فيك وأحسن الله إليك

#11
asm-soft كتب:

واجهت هذه المشكله مع SQLite أثناء قراءه عدد كبير من السجلات من قاعده بيانات PostgreSQL و تسجيلها في ملف SQLite وكان يأخذ وقت كبير جداً حتى يصل إلى السجل رقم 1000 و عند فتح قاعده البيانات SQLite في الذاكره فلا يأخذ تسجيل 10000 سجل أكثر من نصف ثانيه و هنا يوجد مشكله في I/O لذلك مازلت حتى الأن أبحث هل يوجد إعدادات يجب إعدادها عند فتح ملف SQLite أم لا يوجد

عموماً إذا لم يوجد أي إعدادات فأشك أن هناك خطأ ما في درايفر SQLite و هذا سيبقى الخيار الأخير إن لم أعثر على نتيجة أو هناك خطأ ما في إصدار مكتبه SQLite نفسها و يجب تحديثها.

هناك حل ممكن أن يعالج المشكله و هو أن تنشئ قاعده بيانات SQLite في الذاكره ثم تقوم بعمل Backup لها في ملف.

لمعرفه كيف تقوم بعمل Backup

http://www.sqlite.org/backup.html

بارك الله فيك

لقد جربت فعلا إنشاء قاعدة في الذاكرة

  db.setDatabaseName(":memory:");

وكانت النتيجة خيالية

ولكن لم أجرب طريقة ال backup لأن مشكلتي هي اللغة الإنجليزية ولكني سأحاول فهم الطريقة إن شاء الله وتجربتها

جزاك الله عني خير الجزاء

#12
asm-soft كتب:

إضافه:

قم بتحديد قاعده البيانات ففي مثالك استخدم الأتي قبل قاعده while

QSqlDatabase::database("personal").transaction();

و بعد قاعده While ضع الأتي

QSqlDatabase::database("personal").commit();

تمام تمام

بارك الله فيك

يبدو أننا كتبنا المشاركات في وقت واحد

جزاكم الله خيرا جميعا ونفع بكم وجعلكم مباركين أينما كنتم

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…