ADO.NET و ExecuteNonquery: كيفية استخدام DDL
-
29-09-2019 - |
سؤال
أقوم بتنفيذ البرامج النصية 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 متصلة - عفوًا :-). لقد قتلت للتو شيئًا من هذا القبيل في قاعدة الشفرة التي ورثتها (بعد أن تتصرف البرامج النصية الأكثر تعقيدًا مع المريخ والمريخ ، يعد مفيدًا لكود الإنتاج ولكن ليس لأشياء المشرف).