هذه المقالة عملية بحتة ومخصصة لقصتي الحزينة.
التحضير لـ
Zero Touch PROD for RDS (MS SQL) ، والتي كانت جميع آذاننا صاخبة حولها ، قدمت عرضًا تقديميًا (POC - Proof Of Concept) عن الأتمتة: مجموعة من البرامج النصية بوويرشيل. بعد العرض التقديمي ، عندما تلاشى التصفيق العالي المطول ، وتحول إلى تصفيق مستمر ، أخبروني أن كل هذا أمر جيد ، ولكن فقط لأسباب أيديولوجية لدينا جميعًا عبيد جنكينز يعملون تحت لينكس!
هل هذا ممكن؟ لاتخاذ مثل هذا دافئ ، أنبوب ديسيبل من تحت ويندوز ووضعه في حرارة powerhell جدا تحت لينكس؟ أليس هذا قاسيا؟
كان علي أن أغوص في هذا المزيج الغريب من التكنولوجيا. بالطبع ، توقفت كل ما عندي من مخطوطات 30+ عن العمل لدهشتي ، في يوم عمل واحد تمكنت من إصلاح كل شيء. أنا أكتب في المطاردة الساخنة. لذلك ، ما هي المخاطر التي يمكن أن تصادفك عند نقل البرامج النصية powerhell من Windows إلى Linux؟
sqlcmd vs Invoke-SqlCmd
اسمحوا لي أن أذكرك بالفرق الرئيسي بينهما.
تعمل الأداة
sqlcmd القديمة الجيدة
أيضًا على نظام Linux ، مع وظائف متطابقة تقريبًا. لتنفيذ الاستعلام ، نجتاز -Q ، وملف الإدخال كـ -i ، والإخراج -o. هنا فقط أسماء الملفات ، بالطبع ، حساسة لحالة الأحرف. إذا كنت تستخدم -i ، فاكتب في الملف في النهاية:
GO EXIT
إذا لم يكن هناك EXIT في النهاية ، فسيذهب sqlcmd لانتظار المدخلات ، وإذا لم يكن هناك
GO قبل
الخروج ، فلن يعمل الأمر الأخير. كل الإخراج ، يختار ، الرسائل ، الطباعة ، وما إلى ذلك ، يحصل على ملف الإخراج.
إرجاع Invoke-SqlCmd النتيجة كـ DataSet أو DataTables أو DataRows. لذلك ، إذا
تمكنت من معالجة نتيجة التحديد البسيط من خلال
sqlcmd ،
تحليل ناتجها ، فإن إخراج شيء معقد أمر شبه مستحيل: يوجد
Invoke-SqlCmd لهذا الغرض. لكن هذا الفريق له نكاته الخاصة:
- إذا قمت بتمرير الملف إليه عبر -InputFile ، فلن تكون هناك حاجة إلى EXIT ، علاوة على ذلك ، فإنه يعطي خطأ في بناء الجملة
- -OutputFile لا ، الأمر يعود لك النتيجة ككائن
- هناك نوعان من بناء الجملة لتحديد خادم: -ServerInstance -Username -Password -Database وعبر -ConnectionString . بشكل غريب ، في الحالة الأولى ، لا يمكنك تحديد منفذ آخر غير 1433.
- إخراج النص ، من النوع PRINT ، الذي يتم "اكتشافه" بواسطة sqlcmd بطريقة أولية ، يمثل مشكلة بالنسبة Invoke-SqlCmd
- والأهم من ذلك: على الأرجح هذا cmdlet ليس في لينكس الخاص بك!
وهذه هي المشكلة الرئيسية. فقط في شهر مارس ،
أصبح هذا الأمر cmdlet
متاحًا للأنظمة
الأساسية بخلاف النوافذ ، وأخيراً يمكننا المضي قدمًا!
استبدال متغير
Sqlcmd لديه استبدال متغير مع -v ، مثل ذلك:
في البرنامج النصي SQL ، نستخدم البدائل:
set @spid=$(spid) set @age=$(age)
لذلك هنا. في * لا شىء
، لا تعمل البدائل المتغيرة .
يتم تجاهل
الخيار -v .
Invoke-SqlCmd يتجاهل
المتغيرات . على الرغم من أنه يتم تجاهل المعلمة التي تحدد المتغيرات نفسها ، فإن البدائل نفسها تعمل - يمكنك استخدام أي متغيرات من Shell. ومع ذلك ، فقد شعرت بالإهانة من المتغيرات وقررت عدم الاعتماد عليها على الإطلاق ، وتصرفت بشكل تقريبي وبدائي ، حيث أن النصوص البرمجية لـ sql قصيرة:
هذا ، كما فهمت ، هو اختبار من إصدار يونكس.
تحميل الملفات
في إصدار Windows ، كانت أي عملية قمت بها مصحوبة بمراجعة: لقد أجرينا sqlcmd ، ونوعًا من الإساءة في ملف الإخراج ، قمنا بإرفاق هذا الملف بلوحة المراجعة. لحسن الحظ ، كان خادم SQL يعمل على نفس خادم جنكينز ، وقد تم القيام بشيء مثل هذا:
CREATE procedure AuditUpload @id int, @filename varchar(256) as set nocount on declare @sql varchar(max) CREATE TABLE
وبالتالي ، نبتلع ملف BCP بالكامل ، ونشحن جدول التدقيق في حقل nvarchar (max). بالطبع ، لقد انهار هذا النظام برمته ، لأنه بدلاً من خادم SQL ، حصلت على RDS ، ولا يعمل BULK INSERT على \\ UNC بسبب محاولة أخذ قفل خاص إلى ملف ، وبواسطة RDS فإن هذا محكوم عليه بشكل عام من البداية. لذلك قررت تغيير تصميم النظام ، وتخزين خط التدقيق بخط:
CREATE TABLE AuditOut ( ID int NULL, TextLine nvarchar(max) NULL, n int IDENTITY(1,1) PRIMARY KEY )
والكتابة إلى هذا الجدول مثل هذا:
function WriteAudit([string]$Filename, [string]$ConnStr, [string]$Tabname, [string]$Jobname) {
لتحديد المحتوى ، حدد حسب المعرف ، واختر n (هوية) بالترتيب.
في المقالة التالية سوف أتناول بمزيد من التفصيل كيف يتفاعل كل هذا مع جينكينز.