سؤال

أقوم بتنفيذ البرامج النصية SQL لتغيير مخطط قاعدة البيانات. يبدو شيئًا كهذا:

using (var command = connection.CreateCommand())
{
    command.CommandText = script;
    command.ExecuteNonQuery();
}

بالإضافة إلى ذلك ، يتم تنفيذ الأوامر ضمن معاملة.

يبدو أن SCRIP مثل هذا:

Alter Table [TableName]
ADD [NewColumn] bigint NULL

Update [TableName]
SET [NewColumn] = (SELECT somevalue FROM anothertable)

أحصل على خطأ ، لأن NewColumn غير موجود. يبدو أن تحليله والتحقق منه قبل تنفيذها.

عندما أقوم بتنفيذ الأشياء بأكملها في استوديو الإدارة ، يمكنني وضعها GO بين العبارات ، ثم يعمل. عندما أضع GO في البرنامج النصي ، يشكو ADO.NET (بناء جملة غير صحيح بالقرب من "Go").

يمكنني تقسيم البرنامج النصي إلى برامج نصية منفصلة وتنفيذها في أوامر منفصلة ، سيكون من الصعب التعامل مع هذا. يمكنني تقسيمه على كل GO, ، تحليل السيناريو بنفسي. أعتقد فقط أنه يجب أن يكون هناك حل أفضل وأنني لم أفهم شيئًا. كيف يجب تنفيذ البرامج النصية مثل هذه؟


تنفيذي إذا كان أي شخص مهتمًا ، وفقًا لإجابة جون سوندرز:

List<string> lines = new List<string>();
while (!textStreamReader.EndOfStream)
{
    string line = textStreamReader.ReadLine();
    if (line.Trim().ToLower() == "go" || textStreamReader.EndOfStream)
    {
        ExecuteCommand(
            string.Join(Environment.NewLine, lines.ToArray()));

        lines.Clear();
    }
    else
    {
        lines.Add(line);
    }
}
هل كانت مفيدة؟

المحلول

عليك تشغيل كل دفعة بشكل منفصل. على وجه الخصوص ، لتشغيل برنامج نصي قد يحتوي على دفعات متعددة (الكلمات الرئيسية "GO") ، يجب عليك تقسيم البرنامج النصي على الكلمات الرئيسية "GO".

لم تختبر:

string script = File.ReadAllText("script.sql");
string[] batches = script.Split(new [] {"GO"+Environment.NewLine}, StringSplitOptions.None);
foreach (string batch in batches)
{
    // run ExecuteNonQuery on the batch
}

نصائح أخرى

عدم استخدام واحدة من مكتبات ORM الأمل للقيام بذلك؟ جيد :-)

لكي تكون آمنًا تمامًا عند تشغيل البرامج النصية التي تقوم بالتغييرات الهيكلية ، تستخدم SMO بدلاً من SQLClient والتأكد من عدم تشغيل MARS عبر سلسلة الاتصال (سوف تشكو SMO عادةً إذا كان ذلك على أي حال). يبحث عن ServerConnection الفئة والسلطة التنفيذية - DLL مختلفة بالطبع :-)

الفرق هو أن SMO DLL يضع البرنامج النصي كما هو الحال مع SQL بحيث يكون مكافئًا حقيقيًا لتشغيله في SSMS أو عبر خط ISQL CMD. ينتهي التقطيع على GO-S في النمو إلى مسح أكبر بكثير في كل مرة تواجه فيها خللًا آخر (مثل هذا GO يمكن أن يكون في منتصف تعليق متعدد الخطوط ، يمكن أن يكون هناك عبارات متعددة الاستخدام ، يمكن أن يسقط البرنامج النصي من DB SQLClient متصلة - عفوًا :-). لقد قتلت للتو شيئًا من هذا القبيل في قاعدة الشفرة التي ورثتها (بعد أن تتصرف البرامج النصية الأكثر تعقيدًا مع المريخ والمريخ ، يعد مفيدًا لكود الإنتاج ولكن ليس لأشياء المشرف).

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