طريقة الاستعلام عن العديد من قواعد البيانات في ASP.NET

StackOverflow https://stackoverflow.com/questions/305434

سؤال

ما أحاول القيام به هو تشغيل نفس SQL select على العديد من قواعد بيانات أوراكل (على الأقل اثني عشر) ، و عرض الإخراج في Gridview.

لقد اخترق معا شيء يعمل ولكن للأسف انها بطيئة جدا.أعتقد أن تفاقمت بسبب حقيقة أن ما لا يقل عن 1 من عشرة قواعد البيانات سوف دائما تكون غير قابلة للوصول أو في حالة خطأ.

فضلا عن كونها بطيئة لا يسعني التفكير في أنها ليست أفضل طريقة للقيام بذلك, ولا جدا '.صافي مثل.

لقد كتبت شيئا من هذا القبيل في الماضي حلقة بسيطة في PHP الذي يربط فقط لكل db بدوره يعمل sql ويكتب آخر <tr>, ويعمل على الأقل مرتين بسرعة على استفسار معين.ولكن أنا سعيد حقا مع هذا أود أن تحسين المعرفة!

انا اتعلم C# ، ASP.NET لذا يرجى عذر الرهيبة كود :)

public void BindData(string mySQL)
    {
        OracleConnection myConnection;
        OracleDataAdapter TempDataAdapter;
        DataSet MainDataSet = new DataSet();
        DataTable MainDataTable = new DataTable();
        DataSet TempDataSet;
        DataTable TempDataTable;
        string connectionString = "";
        Label1.Visible = false;
        Label1.Text = "";

        foreach (ListItem li in CheckBoxList1.Items)
        {
            if (li.Selected)
            {
                connectionString = "Data Source=" + li.Text + "";
                connectionString += ";Persist Security Info=True;User ID=user;Password=pass;Unicode=True";
                myConnection = new OracleConnection(connectionString);
                try
                {
                    TempDataAdapter = new OracleDataAdapter(mySQL, myConnection);
                    TempDataSet = new DataSet();
                    TempDataTable = new DataTable();
                    TempDataAdapter.Fill(TempDataSet);
                    TempDataTable = TempDataSet.Tables[0].Copy();
                    /* If the main dataset is empty, create a table by cloning from temp dataset, otherwise
                     copy all rows to existing table.*/
                    if (MainDataSet.Tables.Count == 0)
                    {
                        MainDataSet.Tables.Add(TempDataTable);
                        MainDataTable = MainDataSet.Tables[0];
                    }
                    else
                    {
                        foreach (DataRow dr in TempDataTable.Rows)
                        {
                            MainDataTable.ImportRow(dr);
                        }
                    }
                }
                catch (OracleException e)
                {
                    Label1.Visible = true;
                    Label1.Text = Label1.Text + e.Message + " on " + li.Text + "<br>";

                }
                finally
                {
                    if (myConnection != null)
                    {
                        myConnection.Close();
                        myConnection = null;
                    }
                    TempDataSet = null;
                    TempDataAdapter = null;
                    TempDataTable = null;

                }
            }
        }
        GridView1.DataSourceID = String.Empty;
        if (MainDataSet.Tables.Count != 0)
        {
        GridView1.DataSource = MainDataSet;
            if (GridView1.DataSource != null)
            {
                GridView1.DataBind();
            }
        }
    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        BindData(TextBox1.Text);
    }

وذلك بفضل!

تحديث:SQL كود يختلف عن اختبار استخدمت جدا استعلامات بسيطة مثل select sysdate from dual أو select name from v$database.في نهاية المطاف استخدام, سيكون أكثر تعقيدا من ذلك بكثير ، والفكرة هي أنه يجب أن يكون قادرا على تشغيل أي شيء إلى حد كبير ، ومن ثم BindData(TextBox1.Text)

تحديث:سبب الاتصال إلى العديد من قواعد البيانات من ASP.NET رمز بدلا من تخزينها بروك على واحد أو كل dbs ، أو تكرار واحد ديسيبل ، هي ذات شقين.أولا dbs في السؤال يتم تحديثها بشكل متكرر نسخ مماثلة عدة بيئات الإنتاج (عادة تطوير واختبار الدعم لكل عميل) ، لذلك أي شيء الفعلي dbs سوف تكون بحاجة إلى تحديث أو إعادة بنائه بانتظام كما هي reloaded على أي حال.ثانيا, أنا لا أعرف مقدما ما هو نوع من الاستعلام يمكن تشغيل هذا النموذج يتيح لي فقط اكتب مثلا select count (name) from dbusers ضد عشرات من قواعد البيانات دون الحاجة إلى التفكير في تكرار dbusers الجدول الرئيسي ديسيبل.

هل كانت مفيدة؟

المحلول

إذا قمت بتشغيل DataAdapter.ملء الأسلوب على كائن DataTable الجدول سيتم تحديثه مع نتائج الاستعلام.وذلك بدلا من خلق new DataTable و بيانات الكائنات ثم نسخ DataRows يدويا يمكنك فقط إضافة الصفوف إلى نفس الجدول.

محاولة شيء من هذا القبيل (لم تختبر في التعليمات البرمجية C#):

public void BindData(string mySQL)
{
  OracleConnection myConnection;
  // Empty connection string for now
  OracleDataAdapter MainDataAdapter = new OracleDataAdapter(mySQL, ""); 
  DataTable MainDataTable = new DataTable();
  string connectionString = "";
  Label1.Visible = false;
  Label1.Text = "";

  foreach (ListItem li in CheckBoxList1.Items)
  {
    if (li.Selected)
    {
      connectionString = "Data Source=" + li.Text + "";
      connectionString += ";Persist Security Info=True;User ID=user;Password=pass;Unicode=True";
      MainDataAdapter.SelectCommand.Connection.ConnectionString = connectionString
      try
      {
        MainDataAdapter.Fill(MainDataTable);
      }
      catch (OracleException e)
      {
        Label1.Visible = true;
        Label1.Text = Label1.Text + e.Message + " on " + li.Text + "<br>";
      }
    }
  }
  GridView1.DataSourceID = String.Empty;
  GridView1.DataSource = MainDataTable;
  GridView1.DataBind();
}

لم التغييرات التالية:

  • إنشاء بيانات واحدة محول تعيينه حدد الأوامر باستخدام mySQL الخاص بك الاستعلام
  • أعطى اتصال فارغة سلسلة الاتصال
  • إنشاء جدول بيانات الكائن إزالة مجموعات البيانات (تحتاج فقط لهم إذا كان الاستعلام بإرجاع عدة صفوف)
  • غيرت لك حلقة إلى مجرد مجموعة اتصال سلسلة من SelectCommand (قد تضطر إلى تغيير هذا إلى استبدال SelectCommand مع واحد جديد)
  • إزالة اتصال.Close() المكالمات.DataAdapter يقوم بذلك تلقائيا.

و thats عليه.إذا كان لديك قواعد بيانات دون اتصال سوف لا تزال تعاني من التباطؤ ، ولكن على الأقل هو رمز أبسط وأسرع منذ لم يكن لديك نسخ جميع الصفوف بين الجداول الخاصة بك.

أكثر شيء واحد.ربما يمكنك تعيين مهلة الاتصال في سلسلة الاتصال.في محاولة لخفض هذا واحد.

نصائح أخرى

يمكن أن يكون هناك الكثير من العوامل التي تسبب لها أن تكون بطيئة.ما sql يتم تنفيذه يعمل ببطء ؟

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

لماذا لا استخدام النسخ المتماثل للقيام بذلك ... كما تعلمون، قاعدة بيانات مركزية واحدة وهي تجميع لبيانات جديدة من قواعد البيانات الأخرى، ومجرد تنفيذ الاستفسارات الخاصة بك على هذه المجموعة من البيانات وهي <م> لا الذهاب لابد من منصبه.

لماذا لا يتم تشغيل إجراء مخزن واحد على قاعدة بيانات أوراكل واحد، ولها sproc استدعاء قواعد البيانات الأخرى؟ هذه هي الطريقة الصحيحة للعمل مع قواعد البيانات المرتبطة.

يبدو أنك قد تكون أكثر اهتماما في الحصول على إجابة على هذا أكثر عمومية السؤال: كيف يمكنني تنفيذ تشغيل طويلة المهمة دون معلقة على واجهة المستخدم (ASP أو WinForms)?

الجواب على هذا السؤال هو استخدام متعددة المواضيع.أود أن أداء منذ فترة طويلة مهمة مثل هذه في موضوع مستقل و تظهر للمستخدم صفحة مع النتائج الحالية (إما منعش تلقائيا أو مع اياكس ، إلخ).يمكنك حتى الحصول على الهوى و إنشاء المهام لكل المتاحة المعالج للحصول على أقصى استفادة من الجهاز الخاص بك (باستخدام شيء من هذا القبيل موازية امتداد);ولكن هذا يزيد من تعقيد بشكل كبير و يمكن أن يكون من الصعب الحصول على الحق.

إذا لم تكن قد عملت مع المواضيع في .صافي تعليمي كبير يمكن العثور عليها هنا (طريق واحد فقط جون السكيت)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top