الوقت ينفد ، وسرعان ما لن يبقى شيء تقريبًا من هذا التطور ، ولكن لم يكن لدي الوقت لوصف ذلك.

سيكون عن شركة على المستوى الاتحادي مع عدد كبير من الفروع والفروع الفرعية. ولكن ، كالعادة ، بدأ كل شيء منذ وقت طويل بمتجر صغير واحد. على مر السنين ، حدث تطور سريع وعفوي إلى حد ما ، وظهرت الفروع والأقسام والمكاتب الأخرى ، ولم يتم إيلاء الاهتمام اللازم للبنية التحتية لتكنولوجيا المعلومات في تلك الأيام ، وهذا أيضًا حدث متكرر. بالطبع ، تم استخدام 1C77 في كل مكان ، دون أي هامش لأي تكرار وقياس ، لذلك ، كما تعلمون ، في النهاية توصلنا إلى استنتاج مفاده أن أخطبوط فرانكنشتاين تم إنشاؤه بمخالب مربوطة بشريط كهربائي - في كل فرع كان هناك متحولة مستقلة يتم تبادلها مع قاعدة مركزية في وضع "الركبة - الركبة" ، فقط عدد قليل من الكتب المرجعية ، والتي بدونها ، كان من المستحيل على الإطلاق ، والباقي مستقل. لبعض الوقت كانوا راضين بنسخ (عشرات منهم!) من قواعد الفروع في المكتب المركزي ، لكن البيانات الموجودة فيها تخلفت لعدة أيام.
ومع ذلك ، يتطلب الواقع الحصول على المعلومات بشكل أسرع وأكثر مرونة ، وهناك شيء آخر يجب القيام به مع هذا. لا يزال التحويل من نظام محاسبي إلى آخر بمثل هذا النطاق مستنقعًا. لذلك ، تقرر إنشاء مستودع بيانات (DX) ، تتدفق فيه المعلومات من قواعد بيانات مختلفة ، بحيث يمكن للخدمات الأخرى في وقت لاحق والنظام التحليلي في شكل مكعبات ، وتقارير SSRS ، والتسربات تلقي البيانات من هذا القرص المضغوط.
واستشرافا للمستقبل ، سأقول أن الانتقال إلى نظام محاسبة جديد قد حدث تقريبا ، وسيتم قطع معظم المشروع الموصوف هنا في المستقبل القريب باعتباره غير ضروري. آسف ، بالطبع ، ولكن لا يمكن فعل شيء.
فيما يلي مقالة طويلة ، ولكن قبل أن تبدأ في القراءة ، دعني أقول إنه لا يمكنني بأي حال من الأحوال تمرير هذا القرار كمعيار ، ولكن ربما سيجد شخص ما شيئًا مفيدًا فيه.
سأبدأ بنهج عام للمشروع ، والذي تم اختيار SSDT له كبيئة تطوير ، مع النشر اللاحق للمشروع في Git. أعتقد أنه يوجد اليوم ما يكفي من المقالات والبرامج التعليمية التي تصف نقاط القوة في هذه الأداة. ولكن هناك بضع نقاط تقع مشكلتها خارج هذه البيئة.
تخزين التعدادات وإصدارات قواعد البيانات
فيما يتعلق بالإصدارات والتعداد ، فإن متطلبات المشروع تعني:
- راحة تحرير وتتبع التغييرات في إصدار قاعدة البيانات داخل المشروع
- سهولة عرض إصدار قاعدة البيانات من خلال SSMS للمشرفين
- حفظ محفوظات تغييرات الإصدار في قاعدة البيانات نفسها (من ومتى تم النشر)
- تخزين التعدادات في المشروع
- سهولة تحرير وتتبع التغييرات في التحويلات
- تأمين نشر قاعدة البيانات فوق واحد موجود إذا لم يكن هناك إصدار زيادة
- يجب تثبيت إصدار جديد وتسجيل السجل والتحويلات وإعادة الهيكلة في معاملة واحدة والتراجع الكامل في حالة الفشل في أي مرحلة
لأن غالبًا ما تحتوي عمليات النقل على منطق وهي قيم أساسية ، والتي بدونها تصبح إضافة السجلات إلى جداول أخرى مستحيلة (بسبب مفاتيح FK الخارجية) ، فهي في جوهرها جزء من هيكل قاعدة البيانات ، جنبًا إلى جنب مع البيانات الوصفية. لذلك ، يؤدي أي تغيير في أي عنصر تعداد إلى زيادة إصدار قاعدة البيانات ، وإلى جانب هذا الإصدار ، يجب ضمان تحديث السجلات أثناء النشر.
أعتقد أن جميع مزايا حظر النشر دون زيادة الإصدار واضحة ، أحدها هو عدم القدرة على إعادة تشغيل البرنامج النصي للنشر إذا تم تنفيذه بالفعل في وقت سابق بنجاح.
على الرغم من أن شبكة قاعدة البيانات غالبًا ما يقترح استخدام الإصدار الرئيسي فقط (بدون كسور) ، قررنا استخدام الإصدارات بتنسيق XY ، حيث Y هو التصحيح عندما تم تصحيح خطأ مطبعي في وصف الجدول أو العمود أو اسم عنصر القائمة أو أي شيء آخر صغير ، مثل إضافة تعليق إلى إجراء مخزن ، إلخ. في جميع الحالات الأخرى ، تتراكم النسخة الرئيسية.
ربما بالنسبة لشخص ما لا يوجد شيء من
هذا القبيل وكل شيء واضح. لكنني ، في الوقت المناسب ، أخذت الكثير من الأعصاب والطاقة في النزاعات الداخلية حول كيفية تخزين التحويلات في مشروع قاعدة البيانات ، بحيث كان feng shui (
وفقًا لفكرتي عنها ) وكان من المريح العمل معهم ، مع تقليل احتمالية الأخطاء.
مع عمليات النقل ، بشكل عام ، كل شيء بسيط - نقوم بإنشاء ملف PostDeploy في المشروع ونكتب التعليمات البرمجية فيه لملء الجداول. مع عمليات الدمج أو التحريك - هذه هي الطريقة التي تحبها. لقد فضلنا الوميض ، والتحقق المسبق مما إذا كان عدد السجلات في الجدول الهدف يتجاوز عدد السجلات الموجودة في المصدر (المشروع). إذا تجاوز ، يتم طرح استثناء للفت الانتباه إليه ، لأنه غريب. لماذا يوجد عدد أقل من السجلات في المصدر؟ لأن المرء غير ضروري؟ لماذا فجأة؟ وإذا كانت قاعدة البيانات لها روابط بالفعل؟ على الرغم من أننا نستخدم مفاتيح خارجية (FK) ، والتي لن تسمح لك بحذف السجل ، إذا كانت هناك روابط إليه ، فما زلنا نفضل ترك هذا الخيار. ونتيجة لذلك ، تحولت PostDeploy إلى ورقة غير قابلة للقراءة ، لأنه لكل جدول يتم ملؤه ، بالإضافة إلى القيم نفسها ، هناك أيضًا رمز تحقق ودمج وما إلى ذلك.
ومع ذلك ، إذا كنت تستخدم PostDeploy في وضع SQLCMD ، يصبح من الممكن استخراج كتل التعليمات البرمجية في ملفات منفصلة ، ونتيجة لذلك ، تبقى قائمة منظمة من أسماء الملفات فقط لملء التعدادات في PostDeploy.
هناك بعض الفروق الدقيقة مع إصدارات قاعدة البيانات. تناقش الإنترنت لفترة طويلة حول مكان تخزين نسخة قاعدة البيانات ، وكيف يجب أن تبدو ، وبشكل عام ، ما إذا كان يجب تخزينها في مكان ما؟ لنفترض أننا قررنا أننا بحاجة إليها ، في أي مكان من المشروع لتخزينه؟ في مكان ما في البرية من PostDeploy النصي ، أو وضعها في متغير معلن في السطر الأول من البرنامج النصي؟
في رأيي ، لا هذا ولا ذاك. إنه أكثر ملاءمة عندما يتم تخزينه في ملف منفصل وليس هناك أكثر من ذلك.
سيقول شخص ما - هناك dacpac في خصائص المشروع ويمكنك تعيين الإصدار فيه. بالطبع ، يمكنك حتى سحب هذا الإصدار إلى البرنامج النصي الخاص بك ، كما هو موضح
هنا ، ولكن هذا غير مريح - لتغيير إصدار قاعدة البيانات ، تحتاج إلى الذهاب إلى مكان بعيد ، انقر فوق مجموعة من الأزرار. لا أفهم منطق Microsoft - لقد أخفوا ذلك في زاوية بعيدة ، إلى جانب معلمات قاعدة البيانات مثل الفرز ومستوى التوافق وما إلى ذلك ، لأن إصدار قاعدة البيانات يتغير "غالبًا" مثل معلمات الفرز ، أليس كذلك؟ عندما يكون هناك تطور مستمر ، يتراكم الإصدار مع كل عملية نشر جديدة ، حسنًا ، تلعب راحة تتبع التغييرات أيضًا دورًا مهمًا ، لأنه عندما يضيء ملف متغير باسم مألوف ، فهذا شيء واحد ، وعندما يضيء ملف مشروع .sqlproj ، حيث توجد العديد من الخطوط بتنسيق XML ، ومن بينها في مكان ما في وسط الخط ، يتم تمييز رقم واحد تم تغييره ، بطريقة أو بأخرى.

هذا أفضل

ومع ذلك ، ربما تكون هذه مجرد صراصير ويجب ألا تنتبه إليها.
السؤال الآن هو: أين يتم تخزين هذا الإصدار بالفعل في قاعدة البيانات المنشورة. مرة أخرى ، يبدو أن dacpac يقوم بذلك بشكل جميل - يكتب كل شيء على لوحات النظام ، ولكن لرؤية الإصدار ، تحتاج إلى تنفيذ الطلب (أو هل يمكن أن يكون الأمر خلاف ذلك ، لكنني لا أعرف كيفية طبخها؟ يبدو أنه في الإصدارات القديمة من SSMS كانت هناك واجهة لهذا ، والآن لا)
select * from msdb.dbo.sysdac_instances_internal
للمسؤول (وليس فقط) أنها ليست مريحة للغاية. من المنطقي أكثر أن يتم عرض الإصدار مباشرة في خصائص قاعدة البيانات نفسها.

أم لا؟
للقيام بذلك ، تحتاج إلى إضافة ملف إلى المشروع ، مضمن في البناء ، يصف الخصائص المتقدمة
EXECUTE sp_addextendedproperty @name = N'DeployerName', @value = ''; GO EXECUTE sp_addextendedproperty @name = N'DeploymentDate', @value = ''; GO EXECUTE sp_addextendedproperty @name = N'DBVersion', @value = '';
نعم ، إنها فارغة ، وتبدو قبيحة في نص منشور ، ولكن لا يمكنك الاستغناء عنها. إذا لم يتم وصفها في المشروع ، وستكون في قاعدة البيانات ، فسيحاول الاستوديو حذفها في كل مرة يتم نشرها. (كانت هناك محاولات عديدة للتغلب على هذا بإيجاز وبدون خيارات نشر غير ضرورية ، ولكن دون جدوى)
سنقوم بتعيين القيم لهم في PostDeploy النصي.
declare @username varchar(256) = suser_sname() ,@curdatetime varchar(20) = format(getdate(),'dd.MM.yyyy HH:mm:ss') EXECUTE sp_updateextendedproperty @name = N'DeployerName', @value = @username; EXECUTE sp_updateextendedproperty @name = N'DBVersion', @value = [$(DBVersion)]; EXECUTE sp_updateextendedproperty @name = N'DeploymentDate', @value = @curdatetime;
sp_updateextendedproperty
دون أي عمليات تحقق ، لأنه في الوقت الذي تم فيه بدء الحظر من PostDeploy ، تم إنشاء جميع الخصائص بالفعل إذا لم تكن هناك.
حسنًا ، سيكون من الجيد الاحتفاظ بالتاريخ ، حول موضوع من ومتى تم نشر قاعدة البيانات.
يمكن إجراء تغييرات في البيانات الوصفية في المعاملة باستخدام أدوات قياسية عن طريق تحديد مربع
تمكين النصوص البرمجية للمعاملات في نافذة
خيارات النشر المتقدمة . لكن هذه العلامة لا تؤثر على نشر النصوص (Pre / Post) وتستمر في العمل بدون معاملة. بالطبع ، لا شيء يمنع المعاملة من البدء في بداية البرنامج النصي PostDeploy ، ولكنها ستكون معاملة منفصلة عن البيانات الوصفية ، ولدينا مهمة استعادة تغييرات البيانات الوصفية إذا حدث استثناء في PostDeploy.
الحل بسيط - ابدأ المعاملة في PreDeploy ، وقم بتنفيذها في PostDeploy ، ولا تستخدم أي علامات اختيار في إعدادات النشر لهذه الأغراض.
من أجل تخزين نسخة قاعدة البيانات بسهولة في المشروع وتسجيلها في الأماكن المطلوبة أثناء النشر ، يمكنك اللجوء إلى متغيرات SQLCMD. ومع ذلك ، لا أريد تخزين الإصدار في مكان ما في برمجية الشفرة ، أريد أن يكون على السطح.

من أجل وضع إصدار قاعدة البيانات في ملف منفصل وإدارة الإصدار من هناك على مستوى المشروع ، نضيف الكتلة التالية إلى .sqlproj:
<Target Name="BeforeBuild"> <ReadLinesFromFile File="$(ProjectDir)\Properties\DBVersion"> <Output TaskParameter="Lines" PropertyName="ExtDBVersion" /> </ReadLinesFromFile> <WriteLinesToFile File="$(ProjectDir)\\SetPreDepVarsTmp.sql" Lines=":setvar DBVersion $(ExtDBVersion)" Overwrite="true" /> </Target> </Target>
هذه تعليمات لـ MSBuild لقراءة سطر من ملف قبل البناء وإنشاء ملف مؤقت بناءً على البيانات المقروءة. سيقوم MSBuild بإنشاء ملف
SetPreDepVarsTmp.sql
مؤقت ، والذي
:setvar DBVersion $(ExtDBVersion)
السطر
:setvar DBVersion $(ExtDBVersion)
، حيث يمثل
$(ExtDBVersion)
القيمة التي يتم قراءتها من
$(ExtDBVersion)
الذي يخزن نسخة قاعدة البيانات.
بعد هذه المعالجة ، يمكنك الرجوع إلى هذا الملف المؤقت من البرنامج النصي PreDeploy وبدء المعاملة العالمية فيه:
:r .\SetPreDepVarsTmp.sql go :r ".\BeginTransaction.sql"
نسخة وسيطةفي البداية ، تم تعيين ملف ExtendedProperties.sql ليس قيمًا فارغة ، ولكن قيمًا من المتغيرات
EXECUTE sp_addextendedproperty @name = N'DeployerName', @value = [$(DeployerName)]; GO EXECUTE sp_addextendedproperty @name = N'DeploymentDate', @value = [$(DeploymentDate)]; GO EXECUTE sp_addextendedproperty @name = N'DBVersion', @value = [$(DBVersion)];
تم تسجيل المتغيرات بدورها في ملف SetPreDepVarsTmp.sql تلقائيًا بواسطة MSBuild على النحو التالي:
<PropertyGroup> <CurrentDateTime>$([System.DateTime]::Now.ToString(dd.MM.yyyy HH:mm:ss))</CurrentDateTime> </PropertyGroup> <PropertyGroup> <NewLine> -- </NewLine> </PropertyGroup> <Target Name="BeforeBuild"> <ReadLinesFromFile File="$(ProjectDir)\DBVersion"> <Output TaskParameter="Lines" PropertyName="ExtDBVersion" /> </ReadLinesFromFile> <WriteLinesToFile File="$(ProjectDir)\SetPreDepVarsTmp.sql" Lines=":setvar DBVersion $(ExtDBVersion)$(NewLine):setvar DeploymentDate "$(CurrentDateTime)"$(NewLine):setvar DeploymentUser $(UserDomain)\$(UserName)" Overwrite="true" /> </Target>
مع هذا النهج ، لا تحتاج إلى إعادة تثبيت هذه الخصائص في PostDeploy ، ولكن المشكلة هي أن SetPreDepVarsTmp.sql يحتوي على قيم ثابتة وإذا تم إنشاء البرنامج النصي للنشر الآن ، ولكن تم نشره في غضون ساعة ، أو الأسوأ من ذلك ، في اليوم التالي (قام المطور بفحصه لفترة طويلة بصريا ، على سبيل المثال) ، يختلف تاريخ النشر المحدد في الخصائص عن تاريخ النشر الفعلي ولا يتزامن مع التاريخ في التاريخ.
محتوى ملف BeginTransaction.sqlفي الأساس ، هذا مجرد نسخ ولصق من كتلة بدء المعاملة القياسية التي ينشئها الاستوديو عند تحديد خانة الاختيار
تمكين النصوص البرمجية للمعاملات ، ولكننا نستخدمها بطريقتنا الخاصة. في البرنامج النصي ، تم تغيير اسم الجدول المؤقت فقط من
#tmpErrors
إلى
#tmpErrorsManual
بحيث لا يوجد تعارض في الاسم إذا قام شخص ما بتشغيل مربع الاختيار.
IF (SELECT OBJECT_ID('tempdb..#tmpErrors')) IS NOT NULL DROP TABLE
البرنامج النصي PostDeploy declare @TableName VarChar(255) = null
يتيح لك متغير SkipEnumDeploy ، كما أصبح واضحًا بالفعل ، تخطي مرحلة تحديث القوائم ؛ يمكن أن يكون هذا مفيدًا للتغييرات التجميلية الطفيفة. على الرغم من أنه من وجهة نظر الدين ، قد لا يكون هذا صحيحًا ، إلا أنه مفيد بالتأكيد في مرحلة التطور.
ملفات
CaptureTransactionError.sql
و
CommitTransaction.sql
أيضًا لصق نسخ (مع تصحيحات طفيفة) من خوارزمية المعاملات القياسية التي يولدها الاستوديو عند تعيين العلامة أعلاه ، والتي
CaptureTransactionError.sql
الآن بمفردنا.
التقاط المحتوى TransactionError.sql IF @@ERROR <> 0 AND @@TRANCOUNT > 0 BEGIN ROLLBACK; END IF @@TRANCOUNT = 0 BEGIN INSERT INTO
محتوى CommitTransaction.sql EnumTable1.sql المحتوى set @TableName = N'Table1' PRINT N' '+@TableName+'...' begin try set nocount on drop table if exists
عند نشر
Publish
سيكون للبرنامج النصي البنية التالية
من الناحية المثالية ، بالطبع ، أود أن يتم عرض النسخة في وقت النشر

ولكن لا يمكنك سحب القيمة من الملف إلى هذه النافذة ، على الرغم من أن MSBuild يقرأها ويضعها في خاصية ExtDBVersion بمساعدة إرشادات إضافية في ملف .sqlproj ، كما في المثال أعلاه ، ولكن البناء
<SqlCmdVariable Include="DBVersion"> <DefaultValue> </DefaultValue> <Value>$(ExtDBVersion)</Value> </SqlCmdVariable>
لا لفة.
يكتب مطورو التكملة في
مذكرات الويب الخاصة بهم كيف يتم ذلك. وفقًا لإصدارهم ، يكمن السحر في تعليمات
SqlCommandVariableOverride
، وهو أمر بسيط - أضف سطرين إلى ملف مشروع .sqlproj
<ItemGroup> <SqlCommandVariableOverride Include="DBVersion=$(ExtDBVersion)" /> </ItemGroup>
وفعلت. محاولة جيدة ، ولكن لا. ربما عندما تم نشر هذه المدونة ، نجح كل شيء ، ولكن منذ ذلك الحين ، أجريت في هذه أمريكا ثلاث انتخابات رئاسية ولا أحد يعرف التعليمات التي قد تتوقف عن العمل غدًا.
وهنا حاول رفيق واحد كل الخيارات ، ولكن لم ينطلق أي منها.
لذلك ، إما أن تأخذ النسخة من dacpac ، أو تخزنها في PostDeploy ، أو في ملف منفصل ، أو _________ (أدخل نسختك).
التكامل مع 1C
كانت المشكلة الأولى أن 1C77 ليس لديه خادم تطبيقات أو خفي آخر يسمح له بالتفاعل معه دون تشغيل النظام الأساسي. أولئك الذين عملوا مع 1C77 يعرفون أنه ليس لديها وضع وحدة تحكم كامل. يمكنك تشغيل النظام الأساسي مع المعلمات وحتى القيام بشيء بناءً عليها ، ولكن هناك عدد قليل جدًا من معلمات وحدة التحكم وكان الغرض منها مختلفًا. ولكن حتى مع مساعدتهم ، يمكنك الجمع بين مجموعة كاملة. ومع ذلك ، يمكن أن تطير بشكل غير متوقع ، ويمكن أن تبرز نافذة مشروطة وتنتظر أن ينقر شخص ما فوق OK وغيرها من الرموز. وربما المشكلة الأكبر - سرعة المنصة تترك الكثير مما هو مرغوب فيه ... لذلك ، هناك حل واحد فقط - الاستعلامات المباشرة لقاعدة بيانات 1C. نظرًا للهيكل ، لا يمكنك فقط أخذ هذه الاستفسارات وكتابتها ، ولكن الفائدة هي أن هناك مجتمعًا كاملًا طور في وقت واحد أداة رائعة - 1C ++ (1cpp.dll) ، وهو أمر لا يصدق بالنسبة لهم! تسمح لك المكتبة بكتابة الاستعلامات من حيث 1C ، والتي تتحول بعد ذلك إلى أسماء حقيقية للجداول والحقول. إذا كان أي شخص لا يعرف ، فيمكن كتابة الطلب باستخدام اسم زائف وسيبدو هكذا
select from $.
مثل هذا الطلب مفهوم للبشر ، ولكن لا يوجد مثل هذا الجدول والحقل على الخادم ، وهناك أسماء أخرى ، لذلك سيحوله 1C ++ إلى
select SP5278 from SC2235
ومثل هذا الطلب يفهمه الخادم بالفعل. الجميع سعداء ، لا أحد يقسم - لا شخص ولا خادم. هنا ، على ما يبدو ، تم حل المشكلة.
تكمن المشكلة الثانية في مستوى التكوينات: تم استخدام تكوين واحد في الفروع ، وآخر في المكتب المركزي ، والثالث في الفروع! الطبقة؟ !! 1 أعتقد ذلك أيضًا. علاوة على ذلك ، فهي ليست تراثًا نموذجيًا ولا حتى تراثيًا نموذجيًا ، ولكنها مكتوبة بالكامل من الصفر خلال الفايكنج ، وللأسف ، لم يضع أفضل المهندسين المعماريين أساس هذه المؤتمرات ... تنفيذ المستند ، على سبيل المثال ، في كل تكوين لديه مجموعة مختلفة من التفاصيل. ولكن ليس فقط تختلف أسماء بعض الحقول ، وهو أمر أكثر متعة عندما تكون أسماء التفاصيل هي نفسها ، ولكن معنى البيانات المخزنة فيها مختلف.

في التكوينات لا يتم استخدام أي سجلات تقريبًا ، كل شيء مبني على تعقيدات المستندات. لذلك ، كان علي في بعض الأحيان كتابة ورقة كاملة حول معاملة نظيفة ، مع مجموعة من الحالات والانضمام ، لتكرار منطق بعض الإجراءات من التكوين ، والتي تعرض بعض المعلومات في حقل النص في النموذج.
يجب أن نشيد بفريق التطوير ، الذي دعم كل هذه السنوات ما ورثه من "المنفذين" ، إنها مهمة ضخمة - دعم هذا الأمر وحتى تحسين شيء ما. حتى ترى - أنت لا تفهم ، أنا نفسي لم أصدق في البداية أن كل شيء يمكن أن يكون معقدًا للغاية. اسأل - لماذا لا تكتب من جديد؟ عاديا نقص الموارد. كانت الشركة تتطور بسرعة كبيرة لدرجة أنه على الرغم من وجود فريق كبير من المبرمجين ، إلا أنهم ببساطة لم يتمكنوا من مواكبة احتياجات العمل ، ناهيك عن إعادة كتابة المفهوم بأكمله.
نواصل قصة الطلبات. من الواضح أن جميع الكتل لاستخراج البيانات تحولت إلى مخازن بحيث يمكن إطلاقها لاحقًا على جانب الخادم متجاوزًا منصة 1C. كانت القاعدة هي: وحدة تخزين واحدة مسؤولة عن استرداد كيان واحد. لأن لقد تراكمت قائمة الأمنيات في مرحلة البداية بالفعل ، لأنها أصبحت مؤلمة على مر السنين ، ثم ظهرت عشرات ملفات التخزين.
المشكلة الثالثة هي كيفية زيادة سرعة وجودة التطوير ، وكيف يمكن دعم كل هذا الوحش؟ اكتب طلبًا لـ 1C ++ وقم بنسخ ولصق نتيجة تحويله إلى وحدة تخزين؟ إنه أمر غير مريح وممل للغاية ، بالإضافة إلى وجود احتمال كبير للأخطاء - انسخ الخطأ أو الخطأ أو لا تحدد السطر الأخير من الاستعلام وانسخ بدونه. هذا صحيح بشكل خاص عندما يتعلق الأمر باستعلامات 1C المباشرة ، لأنه لا يوجد اسم زائف مثل
الدليل. التسمية. مقالة ، الأسماء الحقيقية فقط
SC2235.SP5278 وبالتالي فإن نسخ طلب من أسفل دليل البضائع إلى متجر يسترد العملاء أمر بسيط للغاية. بالطبع ، من المرجح أن يسقط الطلب بسبب عدم تطابق الأنواع وعدد الحقول في جدول الوجهة ، ولكن هناك لوحات متطابقة ، مثل التعداد ، حيث يوجد عمودين فقط هما ID و Name. بشكل عام ، يبقى فقط لتطبيق نوع من الأتمتة. حسنًا ، كلمات كافية ، دعنا نبدأ العمل!
أردت أن تأتي عملية تطوير التخزين إلى شيء مثل هذا:
- نقوم بإصلاح استعلام SQL بأسماء زائفة وحفظه
- نضغط على زر سحري وعند الخروج نتلقى الإجراء المخزن المصحح على SQL المحولة ، واضحًا للخادم
بعض التفاصيل
لحل المشكلة الثالثة ، تمت كتابة المعالجة الخارجية (.ert). هناك عدد من الإجراءات في المعالجة ، يحتوي كل منها على نص الاستعلام لاستخراج كيان واحد باستخدام اسم زائف ، مثل
select * from $.
في نموذج المعالجة ، يوجد حقل لعرض نتيجة إجراء معين ، أي تم تحويل الطلب إلى نموذج مفهوم للخادم بحيث يمكنك تجربته بسرعة. بالإضافة إلى ذلك ،
يتم دائمًا إضافة
كتلة تصحيح إلى هذا الطلب ، مع تعريف المتغيرات وأسماء قواعد بيانات الاختبار والخوادم والمزيد. يبقى فقط للنسخ واللصق في SSMS والضغط على F5. يمكنك بالطبع تنفيذ هذا الطلب من المعالجة نفسها ، ولكن خطة الطلب وكل ذلك ، حسنًا ، أنت تفهم ... بشكل عام ، هذه هي الطريقة التي يتم بها تصحيح الأخطاء. لأن هناك العديد من التكوينات ؛ في المعالجة ، من الممكن تحويل نفس نص الاستعلام بأسماء زائفة للكائنات إلى استعلامات نهائية للتكوينات المختلفة. في الواقع ، في إحدى المرات المصنفة المرجعية SC123 ، وفي أخرى - SC321. لكن 1C ++ يسمح لك بتحميل تكوينات مختلفة في وقت التشغيل وإنشاء إخراج فردي لكل منها وفقًا للقاموس.
بعد ذلك ، تمت إضافة وضع تشغيل الدُفعات إلى المعالجة ، عندما يبدأ تلقائيًا كل من الإجراءات لكل تكوين ، ويتم كتابة إخراج كل منها إلى ملفات .sql (فيما يلي الملفات الأساسية). وبالتالي ، نحصل على مجموعة من مجموعات الملفات الأساسية ، والتي يجب أن تتحول تلقائيًا إلى إجراءات مخزنة باستخدام VS. تجدر الإشارة إلى أن الملفات الأساسية تتضمن
كتلة تصحيح .
يبدو ، لماذا لا يتم الاستنتاج الفوري للملفات النهائية للإجراءات المخزنة والاحتفاظ بكل شيء في هذه المعالجة؟ والحقيقة هي أنه بالنسبة لبعض الاختبارات ، من الضروري تشغيل إصدارات تصحيح الاستعلامات على دفعات يتم فيها الإعلان عن جميع المتغيرات ، بالإضافة إلى أنني أريد أن تتم إدارة أسماء الإجراءات المخزنة من VS ، متجاوزة 1C ، لأن هذا منطقي ، أليس كذلك؟
بالمناسبة ، يتم تخزين الملفات الأساسية أيضًا في المشروع ، بالطبع ، ملفات الإجراءات المخزنة الجاهزة ، بالطبع. في أي وقت ، بدون بدء 1C ، يمكنك فتح الملف الأساسي في SSMS وتنفيذه دون عناء بإعلانات متغيرة.
في المعالجة ، جميع الإجراءات مع الطلبات هي أيضًا قالب ، لها نفس مجموعة المعلمات ، ولكن في هذا الإجراء أو ذاك يتم استخدام المعلمات الضرورية فقط. في البعض ، كل شيء متضمن ، وفي البعض الآخر يكفي. لذلك ، تأتي إضافة إجراء جديد لنسخ النموذج وملء المعلمات مع الاستعلامات نفسها.
رمز أحد إجراءات المعالجة ، والذي سيتحول بعد ذلك إلى إجراء مخزن

الاستعلام الأخير يسير على النحو التالي:
++"("+OPENQUERY()+")"+
ظهور المعالجة

عند تبديل التكوينات ، تتغير قائمة العناصر المتاحة (الضرورية) لتفريغ العناصر في قائمة البيانات. إن أمكن ، كان رمز الإجراء في 1C موحّدًا قدر الإمكان. إذا تم استخراج الأطراف المقابلة وكانت هذه الدلائل غير متناسقة في تكوينات مختلفة ، فهناك حالات مختلفة داخل إجراء التوليد ، مثل: تم إصلاح هذه الكتلة للجميع ، تتم إضافة هذا إلى الطلب النهائي لمثل هذا Conf ، وهناك واحد للآخر. اتضح أنه في الإجراءات المخزنة لكيان واحد ولكن التكوينات المختلفة ، يمكن أن تختلف ليس فقط حسب أسماء الجداول ، ولكن حسب مجموعات كاملة من الصلات الموجودة في واحد وتغيب في أخرى. مجموعة حقول الإخراج ، بالطبع ، هي نفسها وتتوافق مع جدول المتلقي أو حاوية حزمة SSIS ، بعض الحقول مسدودة بأجزاء للتكوينات التي لا تكون فيها هذه التفاصيل من حيث المبدأ.
الزر السحرييحتوي Visual Studio على أدوات مثل MSbuild وقوالب T4 الرائعة. لذلك ، كزر سحري ، تم كتابة برنامج نصي في C # لـ T4 ، والذي:
- تسجيل تكوين فارغ في التسجيل (وإلا سيعرض 1C نافذة مشروطة مع اقتراح لتسجيل conf وانتظر إجراءات المستخدم)
- ينشئ قاعدة بيانات فارغة لهذا الكون على خادم SQL ، لأنه بدونها سيعطي 1C خطأ
- تطلق 1C ومن خلال OLE يطلب منها تنفيذ المعالجة (نفس .ert) ، وكذلك نقل GUID الفريد إلى 1C
- الإخراج هو سلسلة من الملفات ذات الطلبات الجاهزة (المحولة) وملف علامة ، يتم كتابة GUID المستلمة عند بدء التشغيل
- يتم حذف تسجيل conf من التسجيل ويتم حذف قاعدة بيانات فارغة مؤقتة من الخادم
- للتحقق من محتويات ملف الرمز المميز. إذا احتوى ملف العلامة على المعرف الفريد العمومي (GUID) الذي مررناه إلى 1C عند بدء تشغيله ، فهذا يعني أنه عمل حتى النهاية ، ولم يتلف ، وما إلى ذلك ، ثم انتقل إلى الخطوة التالية ، أو نعرض خطأ
- نحن نصنع مخازن.
- نقوم بفك ملف .ert مع gcomp للحصول على نصوص الوحدة ونماذج المعالجة ، حسنًا ، نتحول إلى Unicode ، للإرسال اللاحق إلى Git وعرضه بشكل صحيح هناك. بالنسبة لأولئك الذين لم يعملوا مع 1C: ملف .ert هو ثنائي والاستوديو ، مع git ، ضربات أنه تم تغيير ملف .ert ، ولكن ليس من الواضح ما الذي تغير فيه بالضبط ، ربما قام شخص فقط بنقل الزر بكسل واحد إلى اليسار (الذي غير مقبول بدون مبرر)
T4 , ( , ) . , . , , , , - — 1.
, , , , , . — 1, 1, - .
: ?
- / ;
- VS , ;
- 4;
. تم.
?لأن , , .sqlproj,
<ItemGroup> <None Include=" \1.sql"> <None Include=" \2.sql"> <None Include=" \3.sql"> </ItemGroup>
<ItemGroup> <Content Include=" \*.sql" /> </ItemGroup>
« ». , , , :)
, , (, ) . ( ), , - - - , .
, . . , , , , , ( ), . , ( , ) , , , . , . , , , , , ( , 1, , MD ).
,
OPENQUERY , 1 , , , ,
EXEC .
OPENQUERY , , , .
177 ( ) SQL2000, varchar(max) , varchar(8000), 9, … , EXEC(@SQL1+@SQL2). , SQL2016, SQL2000. , , .
select ... from ( select ... from @1CDBName.dbo.$. join @1CDBName.dbo.$. join ... where xxx = 'hello!' ^
CREATE PROCEDURE [dbo].[SP1] @LinkedServerName varchar(24) ,@1CDBName varchar(24) AS BEGIN Declare @TSQL0 varchar(8000), @TSQL1 varchar(8000), @TSQL2 varchar(8000) set @TSQL0=' select ... from OPENQUERY('+@LinkedName+','' select ... from '+@1CDBName+'.dbo.DH123. join '+@1CDBName+'.SC123. ... where '; set @TSQL1=' xxx = ''''hello!'''' join ... join ... )'' join ... '''; set @TSQL2=' ... EXEC(@TSQL0+@TSQL1+@TSQL2) END
— . (, ) , , , , , , OPENQUERY 8 .
.ert , .. , .
, .
ETL
, ( ). (Stage). , ETL SSIS , , , , . . ( ), .
, ( ) , , (.. ), , .
, , . , . zabbix.
.
لأن 1 , , . , ,
truncate
.
, ( ) -, « 1-» .
SSIS


,
SSIS
SQL Server (SQL Server Destination), ,
OLE DB (OLE DB Destination).
, , , . , , . (, )
. , , , (/ ).
.
, ( ). على سبيل المثال , . , , . - — . .
, (.. ) .
, , .
ملاحظة
, , , , . — , . - , , .