سؤال

أنا أحاول بناء على الرسم البياني التبعية من الجداول بناء على المفاتيح الخارجية بينهما.هذا الرسم البياني يجب أن تبدأ مع التعسفي اسم الجدول كما جذورها.يمكنني إعطاء اسم الجدول البحث عن الجداول المرجعية باستخدام all_constraints عرض ، ثم ابحث عن الجداول المشار إليها ، وهلم جرا ، ولكن هذا سيكون فظيع غير فعالة.كتبت العودية الاستعلام الذي يقوم بذلك جميع الجداول ، ولكن عندما أضيف:

START WITH Table_Name=:tablename

أنه لا عودة الشجرة بأكملها.

هل كانت مفيدة؟

المحلول

    select parent, child, level from (
select parent_table.table_name parent, child_table.table_name child
 from user_tables      parent_table,
      user_constraints parent_constraint,
      user_constraints child_constraint,
      user_tables      child_table
where parent_table.table_name = parent_constraint.table_name
  and parent_constraint.constraint_type IN( 'P', 'U' )
  and child_constraint.r_constraint_name = parent_constraint.constraint_name
  and child_constraint.constraint_type   = 'R'
  and child_table.table_name = child_constraint.table_name
  and child_table.table_name != parent_table.table_name
)
start with parent = 'DEPT'
connect by prior child = parent

يجب أن تعمل (استبدال اسم الجدول بالطبع) على افتراض أن كل شيء في نفس المخطط.استخدام DBA_ إصدارات قاموس البيانات الجداول وشروط المالك R_OWNER الأعمدة إذا كنت تحتاج إلى التعامل معها عبر مخطط التبعيات.على مزيد من التفكير, وهذا لا تراعي المرجعي الذاتي القيود (أيالقيد في الجدول EMP أن MGR عمود مراجع EMPNO عمود) أيضا لذا يجب تعديل التعليمات البرمجية للتعامل مع هذه الحالة إذا كنت بحاجة إلى التعامل مع المرجعي الذاتي القيود.

لأغراض الاختبار, لقد تم إضافة عدد قليل من الجداول الجديدة إلى سكوت المخطط أيضا الرجوع إلى قسم الجدول (بما في ذلك الحفيد التبعية)

SQL> create table dept_child2 (
  2  deptno number references dept( deptno )
  3  );

Table created.

SQL> create table dept_child3 (
  2    dept_child3_no number primary key,
  3    deptno number references dept( deptno )
  4  );

Table created.

SQL> create table dept_grandchild (
  2    dept_child3_no number references dept_child3( dept_child3_no )
  3  );

Table created.

و التحقق من أن الاستعلام بإرجاع الناتج المتوقع

SQL> ed
Wrote file afiedt.buf

  1  select parent, child, level from (
  2  select parent_table.table_name parent, child_table.table_name child
  3   from user_tables      parent_table,
  4        user_constraints parent_constraint,
  5        user_constraints child_constraint,
  6        user_tables      child_table
  7  where parent_table.table_name = parent_constraint.table_name
  8    and parent_constraint.constraint_type IN( 'P', 'U' )
  9    and child_constraint.r_constraint_name = parent_constraint.constraint_name
 10    and child_constraint.constraint_type   = 'R'
 11    and child_table.table_name = child_constraint.table_name
 12    and child_table.table_name != parent_table.table_name
 13  )
 14  start with parent = 'DEPT'
 15* connect by prior child = parent
SQL> /

PARENT                         CHILD                               LEVEL
------------------------------ ------------------------------ ----------
DEPT                           DEPT_CHILD3                             1
DEPT_CHILD3                    DEPT_GRANDCHILD                         2
DEPT                           DEPT_CHILD2                             1
DEPT                           EMP                                     1

نصائح أخرى

أبسط طريقة للقيام بذلك هو نسخ جميع FK إلى معلومات بسيطة 2-عمود (والد الطفل) الجدول ، ثم استخدام الخوارزمية التالية:

while (rows left in that table)
  list = rows where table name exists in child but not in parent
  print list
  remove list from rows

هذا كل شيء.في الأساس, عليك أولا طباعة و إزالة جميع العقد التي لا تعتمد على أي شيء.بعد أن يجري بعض العقد الأخرى سوف تحصل مجانا و يمكنك تكرار العملية.

P. S.تأكد من أنك لا أدخل الذاتي الرجوع إلى الجداول في القائمة الأولية (الطفل=الأم)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top