علة أوراكل؟ حدد إرجاع أي dupes، إدراج من تحديد لديه صفوف مكررة

StackOverflow https://stackoverflow.com/questions/1868417

  •  18-09-2019
  •  | 
  •  

سؤال

أحصل على بعض السلوك الغريب من مثيل أوراكل أعمل عليه. هذا هو 11gr1 على إيتانيوم، لا لور، لا شيء يتوهم. في النهاية أتحرك البيانات من مثيل Oracle إلى آخر في سيناريو مستودع البيانات.

لدي عرض نصف معقد يعمل على رابط DB؛ 4 ينضم إلى الجداول الكبيرة والعيش و 5 اليسار ينضم إلى جداول منتصف الحجم.

إليك المشكلة: عندما أقوم باختبار العرض في مطور SQL (أو SQL * Plus) يبدو جيدا، لا تكرار على الإطلاق. ومع ذلك، عندما أستخدم طريقة العرض فعليا لإدراج البيانات في جدول أحصل على عدد كبير من Dupes.

تحرير: - البيانات تدخل في جدول فارغ. جميع الجداول في الاستعلام موجودة في رابط قاعدة البيانات. الشيء الوحيد الذي تم تمريره في الاستعلام هو تاريخ (مثل إدراج في الهدف SELECT * من العرض حيث View.datecol = DQUEREDATE) -

لقد حاولت إضافة وظيفة row_number () إلى عبارة SELECT، مقسمة بواسطة PK للعرض. تعود جميع الصفوف مرقمة ك 1. مرة أخرى، وتشغيل نفس العبارة كإدراج ينشئ نفس الوثائق كما كان من قبل والآن مرقمة بسهولة. عدد الصفوف المدخنة ليس هو نفسه لكل مفتاح. بعض السجلات موجودة 4 مرات بعض الوجود مرة واحدة فقط.

أجد هذا للسلوك ليكون حيرا للغاية. :) يذكرني بالعمل مع Teradata حيث قمت بتعيين الجداول (صفوف فريدة فقط) وطاولات Multiset (الصفوف المكررة المسموح بها) ولكن Oracle لا يوجد لديه هذه الوظائف.

يجب أن تتصرف تحديد الصفوف التي ترجع إلى العميل بشكل متطابقة إلى واحدة تدرج تلك الصفوف إلى موقع آخر. لا أستطيع أن أتخيل سبب شرعي لهذا الحدوث، لكن ربما أعاني من فشل الخيال. ؛)

أتساءل عما إذا كان أي شخص آخر قد شهد هذا أو إذا كان خطأ على هذه المنصة.

المحلول

شكرا و "حدد * من الجدول (dbms_xplan.display)؛". شرح ذلك في الواقع يتم استخدامها بالنسبة إلى إدراج مختلف جدا عن التحديد.

بالنسبة إلى تحديد معظم عمليات الخطة هي "وصول الجدول عن طريق فهرس Rowid" و "الفهرس الفريد". تحتوي كتلة "معلومات المعلومات المسندية" على جميع عمليات الاستعلام والمرشحات من الاستعلام. في النهاية تقول "ملاحظة - بيان بعيد بالكامل".

لإدراج عدم وجود إشارة إلى الفهارس. كتلة "معلومات المسنات" هي ثلاثة خطوط فقط وعروض كتلة "SQL البعيدة" الجديدة 9 بيانات SQL الصغيرة.

قامت قاعدة البيانات بتقسيم استفستي إلى 9 نقاط استعلامات ثم محاولات الانضمام إليها محليا. عن طريق تشغيل الاختيار الأصغر، لقد حددت مصدر التكرارات.

أعتقد أن هذا خطأ في مترجم Oracle حول الروابط عن بعد. إنه يخلق عيوب منطقية عند إعادة كتابة SQL. أساسا المترجم لا يطبق بشكل صحيح جملة حيث. كنت فقط اختبرها وأعطتها في قائمة 5 مفاتيح لإعادة. حدد يجلب 5 صفوف. إدراج يضع 77000 صفوف في الهدف و يتجاهل تماما في القائمة.

{لا تزال تبحث عن وسيلة لإجبار السلوك الصحيح، قد تضطر إلى طرح عرض الرأي في قاعدة البيانات البعيدة على الرغم من أن هذا ليس مثاليا من وجهة نظر التطوير. سأقوم بتحرير هذا عندما حصلت عليه ...}

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

المحلول

يبدو أنه علة Oracle، لقد وجدنا هذا العمل التالي: إذا كنت تريد ذلك "insert into select ..."اعمل مثل الخاص بك"select ..."، يمكنك حمل الاختيار الخاص بك في اختيار فرعي.

علي سبيل المثال :

select x,y,z from table1, table2, where ...

-> لا مكررة

insert into example_table
select x,y,z from table1, table2, where ...

-> خطأ مكررة

insert into example_table
select * from (
       select x,y,z from table1, table2, where ...
)

-> لا مكررة

يعتبر

نصائح أخرى

الشيء الوحيد الذي يتبادر إلى الذهن هو أن خطة محسن عموما للاختيار ستفضل خطة first_rows لإعطاء الصفوف مرة أخرى إلى المتصل مبكرا، ولكن إدراج ... حدد يفضل خطة All_rows كما ستضطر إلى تسليم مجموعة البيانات كاملة. أتحقق من خطط الاستعلام باستخدام DBMS_XPLAN.DISPLAY_CURSOR (باستخدام SQL_ID من V $ SQL).

لدي عرض نصف معقد يعمل على رابط DB؛ 4 ينضم إلى الجداول الكبيرة والعيش و 5 اليسار ينضم إلى جداول منتصف الحجم. ... جميع الجداول في الاستعلام موجودة في رابط قاعدة البيانات

مرة أخرى، بقعة مشكلة محتملة. إذا كانت جميع الجداول الموجودة في المحددة في الطرف الآخر من رابط DB، فسيتم إرسال الاستعلام بأكمله إلى قاعدة البيانات البعيدة وإرجاع النتائج. بمجرد رمي "إدراج"، من المرجح أن تتولى قاعدة البيانات المحلية مسؤولية الاستعلام وسحب جميع البيانات من جداول الأطفال. ولكن قد يعتمد ذلك على ما إذا كان العرض يتم تعريف العرض في قاعدة البيانات المحلية أو قاعدة البيانات البعيدة. في الحالة الأخيرة، فيما يتعلق بالمحسن المحلي، يوجد كائن بعيد واحد فقط ويحصل على بيانات من ذلك، وستقوم قاعدة البيانات البعيدة بالانضمام.

ماذا يحدث إذا ذهبت فقط إلى DB البعيد والقيام بإدراج على جدول هناك؟

هذا خطأ في معالجة Oracle للانضمام عبر روابط DB. لدي موقف أبسط لا ينطوي على إدراج مقابل تحديد. إذا قمت بتشغيل استعلامي عن بعد، أحصل على صفوف مكررة، ولكن إذا قمت بتشغيله محليا، فأنا لا. الفرق الوحيد بين الاستفسارات هو "@ ..." إلحاق جداول الجداول في الاستعلام عن بعد. أنا استعلام قاعدة بيانات 9i من قاعدة بيانات 10.2 باستخدام Oracle SQL Developer 3.0.

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

إنه غبي تقريبا لأن علة قاعدة بيانات Oracle الأخرى التي تحظر على جداول الاستعلام التي تحتوي على محددات LOB باستخدام بناء جملة ANSI. فقط بناء جملة Oracle!

تحدث عدة خيارات لي.

  1. كانت Dupes التي تراها بالفعل في الجدول الوجهة؟

  2. إذا كان لديك، فأرجع الجدول الذي تقوم بإدراجه فيه، (؟)، ثم يتفاعل الإدراج مع تحديد في مجتمعة

    إدراج ... حدد ... من ...

في مثل هذه الطريقة (المنتجات الديكارتية؟) لإنشاء التكرارات

لا أستطيع أن أساعد ولكن أعتقد أنه ربما تعاني من تأثير جانبي عن شيء آخر يتعلق بالطاولة. هل هناك أي مشغلات قد تكون تلمع البيانات؟

كيف حددت أنه لا توجد أدوات في الجدول الأصلي؟

كما لاحظ البعض الآخر أن هذا هو التفسير المبسط لهذا السلوك الغريب.

افحص JOINs بعناية. من المحتمل أن يكون لديك مكررات في الجداول الفردية، ولكن الإنضمام المشترك يمكن أن يسبب غير مقصود CROSS JOINS بحيث يحتوي مجموعة النتائج الخاصة بك على تكرارات بسبب التعددية، عند إدراجها، ينتهك هذا قيد التفرد في جدول الوجهة الخاص بك.

ما أقوم به في هذه الحالة هو عش الاستعلام في طريقة عرض أو CTE وحاول اكتشاف التكرارات مباشرة من SELECT:

WITH resultset AS (
    -- blah, blah
)
SELECT a, b, c, COUNT(*)
FROM resultset
GROUP BY a, b, c
HAVING COUNT(*) > 1

أود أن أقترح الحصول على خطة حول الاستعلام الذي تقوم بتشغيله والبحث عن الديكارتانية هناك. هذا يمكن أن يشير إلى حالة مفقودة تسبب صفوف مكررة.

نظرا لأن Bop قد اقترح بالفعل أن هذا السلوك قد يحدث إذا كنت تستخدم تسجيل دخول مختلف في SQLPlus إلى تسجيل الدخول عند تشغيل "إدراجك". (هذا إذا كان تسجيل الدخول الآخر لديه جدول / عرض / مرادف بنفس الاسم)

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