17/09/2026
في تطبيقات المؤسسات الكبيرة، مش بتلاقي كل حاجة في سكيمة واحدة. ممكن يكون عندك سكيمة HR، وسكيمة تانية للـ Finance، وتالتة للـ Inventory... إلخ. الكود بتاعك بيتصل بقاعدة البيانات باستخدام user معين (يبقى ده الـ Schema A)، لكن الـ package اللي محتاج تناديها فعليًا "ساكنة" في سكيمة تانية (Schema B).
المشكلة إن Oracle مبيفرقش في رسالة الخطأ بين "الكائن مش موجود"، "الكائن موجود بس معطوب"، "الاسم غلط"، أو "الصلاحيات ناقصة" — كل دول بيطلعوا نفس الرسالة بالظبط:
PLS-00201: identifier 'SCHEMA_B.PKG_SOME_PACKAGE' must be declared
ليه الناس بتقفز على الصلاحيات؟
لأن ده الحل "المشهور" واللي غالبًا فعلاً بيكون هو السبب في حالات كتير، فبقى رد فعل تلقائي. المشكلة إنك لو منحت الصلاحية والمشكلة كانت حاجة تانية (زي اسم غلط)، هتفضل تلف في حلقة مفرغة من التجربة والخطأ.
الخطوات بالتفصيل
1. التأكد من الاسم والسكيمة
مش مجرد "أنا متأكد إن الاسم صح" — لازم تستعلم فعليًا:
SELECT object_name, object_type, status
FROM all_objects
WHERE owner = 'SCHEMA_B'
AND object_name LIKE '%SOME_PACKAGE%';
ليه؟ لأن سيناريوهات زي دي شائعة جدًا: حد نسخ كود من إجراء تاني وغيّر بعض الحاجات بس نسي يغيّر اسم الـ package، أو الاسم كان PKG_SOME_PACKAGE وبقى PKG_SOME_PACKAGE_V2 بعد تحديث، أو حتى فرق بسيط في spelling محدش لاحظه.
2. حالة الكائن (status)
الكائن ممكن يكون موجود بالظبط بنفس الاسم، بس يكون INVALID. ده بيحصل غالبًا لما كائن تاني بيعتمد عليه (dependency) بيتغيّر — زي جدول اتضاف له عمود، أو إجراء تاني جوه نفس الـ package اتعدّل وسبب خطأ compilation. النتيجة: الـ package "موجودة" لكن مش قابلة للاستخدام، والخطأ اللي بيطلع بيشبه مشكلة صلاحيات تمامًا مع إنه مشكلة compilation.
3. تطابق البارامترات
خصوصًا مع الـ packages اللي فيها overloading (نفس اسم الإجراء بس بعدد/نوع بارامترات مختلف)، لو الكود بتاعك بيبعت بارامترات مش متطابقة تمامًا مع أي نسخة من الإجراء، Oracle ممكن يفشل في resolve الاستدعاء بالكامل ويطلع نفس رسالة الخطأ، مش رسالة واضحة تقول "بارامتراتك غلط".
4. الصلاحيات (بعد ما تتأكد من كل اللي فوق)
هنا بس، لو كل حاجة فوق سليمة، تبقى فعلاً مشكلة صلاحيات:
GRANT EXECUTE ON PKG_SOME_PACKAGE TO SCHEMA_A_USER;
CREATE SYNONYM PKG_SOME_PACKAGE FOR SCHEMA_B.PKG_SOME_PACKAGE;
كده الكود بيستدعي PKG_SOME_PACKAGE بس، من غير بادئة، ولو الكائن اتنقل مكانه يومًا (نقلوه لسكيمة تالتة مثلاً)، بتعدّل الـ synonym بس مش كل نقطة استدعاء في الكود كله.
الخلاصة العملية
اتبع الترتيب ده زي checklist، من غير ما تقفز خطوة: اسم → status → بارامترات → صلاحيات → synonym. ده أسرع في المجمل من إنك تخمّن وتمنح صلاحيات عشوائي وتكتشف بعد نص ساعة إن المشكلة كانت حاجة تانية من ال