هذه الرسالة لا علاقة لها بإعدادات النظام ولا برصيد الحساب، وإنما تأتي من SQL Server نفسه، وسببها مشكلة قديمة موروثة في قواعد البيانات المنشأة منذ سنوات.
في التصميم القديم كانت حقول الحسابات الموجودة في العملاء والموردين والموظفين وباقي أنواع الذمم تُنشأ كمفاتيح خارجية (Foreign Keys) حقيقية تشير إلى جدول Account. وبما أن الحساب موجود تقريباً في كل جداول قاعدة البيانات، فإن أمر الحذف الذي يبنيه SQL Server يضطر إلى فحص مئات الجداول المرتبطة في وقت واحد، فينفد من مُحسِّن الاستعلام (Query Optimizer) الحيز المخصص له أثناء تخطيط الاستعلام، فتظهر هذه الرسالة.
ونفس المشكلة بالضبط كانت تحدث عند حذف المستخدمين والموظفين والمرفقات، ولهذا السبب تم تغيير التصميم بحيث لم تعد تُنشأ قيود على مستوى قاعدة البيانات للحقول التي تشير إلى جداول موجودة في كل الكيانات تقريباً (الحسابات، المستخدمون، الموظفون، المرفقات). لذلك لا تظهر المشكلة في قواعد البيانات الجديدة، أما قاعدة البيانات القديمة فما زالت تحمل تلك القيود.
الحل هو حذف المفاتيح الخارجية المتبقية التي تشير إلى الحسابات، وذلك بتنفيذ السكربت التالي مرة واحدة على قاعدة البيانات:
while(exists(select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS t left join INFORMATION_SCHEMA.KEY_COLUMN_USAGE k on k.CONSTRAINT_NAME = t.CONSTRAINT_NAME
where CONSTRAINT_TYPE='FOREIGN KEY' and COLUMN_NAME in ('mainAccount_id','account1_id','account2_id','account3_id','account4_id','account5_id','account6_id','account7_id','account8_id','account9_id','account10_id','account11_id','account12_id','account13_id','account14_id','account15_id','account16_id','account17_id','account18_id','account19_id','account20_id','account_id')))
begin
declare @sql nvarchar(2000)
SELECT TOP 1 @sql=('ALTER TABLE ' + t.TABLE_SCHEMA + '.[' + t.TABLE_NAME
+ '] DROP CONSTRAINT [' + t.CONSTRAINT_NAME + ']')
from INFORMATION_SCHEMA.TABLE_CONSTRAINTS t left join INFORMATION_SCHEMA.KEY_COLUMN_USAGE k on k.CONSTRAINT_NAME = t.CONSTRAINT_NAME
where CONSTRAINT_TYPE='FOREIGN KEY' and COLUMN_NAME in ('mainAccount_id','account1_id','account2_id','account3_id','account4_id','account5_id','account6_id','account7_id','account8_id','account9_id','account10_id','account11_id','account12_id','account13_id','account14_id','account15_id','account16_id','account17_id','account18_id','account19_id','account20_id','account_id')
exec (@sql)
end
وهذا الإجراء آمن، لأن النظام يتحقق من صحة هذه العلاقات داخل التطبيق نفسه وليس عن طريق قيود قاعدة البيانات. بعد تنفيذ السكربت أعد محاولة حذف الحساب ولن تظهر الرسالة مرة أخرى.
ملاحظة: خذ نسخة احتياطية من قاعدة البيانات قبل تنفيذ أي تعديل على الـ schema، ونفّذ السكربت خارج أوقات العمل إن أمكن.
إذا ظهرت نفس الرسالة عند حذف مستخدم أو موظف أو مرفق، فهناك سكربت مماثل لكل حالة في صفحة العمليات المتعلقة بقاعدة البيانات: