هذه المقالة عملية بحتة ومخصصة لقصتي الحزينة.
التحضير لـ 
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 (هوية) بالترتيب.
في المقالة التالية سوف أتناول بمزيد من التفصيل كيف يتفاعل كل هذا مع جينكينز.