ORA-30926: ไม่สามารถรับชุดแถวที่มั่นคงในตารางต้นทาง


129

ฉันได้รับ

ORA-30926: ไม่สามารถรับชุดแถวที่มั่นคงในตารางต้นทาง

ในแบบสอบถามต่อไปนี้:

  MERGE INTO table_1 a
      USING 
      (SELECT a.ROWID row_id, 'Y'
              FROM table_1 a ,table_2 b ,table_3 c
              WHERE a.mbr = c.mbr
              AND b.head = c.head
              AND b.type_of_action <> '6') src
              ON ( a.ROWID = src.row_id )
  WHEN MATCHED THEN UPDATE SET in_correct = 'Y';

ฉันรันtable_1มันมีข้อมูลและฉันก็รันเคียวรีภายใน ( src) ซึ่งมีข้อมูลด้วย

เหตุใดจึงเกิดข้อผิดพลาดนี้และจะแก้ไขได้อย่างไร

คำตอบ:


202

ซึ่งมักเกิดจากรายการที่ซ้ำกันในข้อความค้นหาที่ระบุไว้ใน USING clause ซึ่งอาจหมายความว่า TABLE_A เป็นตารางหลักและ ROWID เดียวกันจะถูกส่งกลับหลายครั้ง

คุณสามารถแก้ปัญหาได้อย่างรวดเร็วโดยใช้ DISTINCT ในแบบสอบถามของคุณ (อันที่จริงถ้า 'Y' เป็นค่าคงที่คุณไม่จำเป็นต้องใส่ไว้ในแบบสอบถาม)

สมมติว่าคำถามของคุณถูกต้อง (ไม่ทราบตารางของคุณ) คุณสามารถทำสิ่งนี้ได้:

  MERGE INTO table_1 a
      USING 
      (SELECT distinct ta.ROWID row_id
              FROM table_1 a ,table_2 b ,table_3 c
              WHERE a.mbr = c.mbr
              AND b.head = c.head
              AND b.type_of_action <> '6') src
              ON ( a.ROWID = src.row_id )
  WHEN MATCHED THEN UPDATE SET in_correct = 'Y';

1
นี่อาจเป็นสาเหตุที่วิธีการอื่น ๆ (สำหรับฉัน) ส่งคืนข้อผิดพลาดอื่น ๆ ให้ฉันด้วย (เช่น 'ขั้นตอนฟังก์ชันแพ็คเกจหรือประเภทไม่ได้รับอนุญาตที่นี่' และ 'ไม่สามารถแก้ไขคอลัมน์ที่แมปกับข้อผิดพลาดของตารางที่ไม่ได้เก็บรักษาคีย์ขณะพยายาม แทรกเข้าไปในมุมมอง ') ~ ถ้ามันช่วยคนอื่นฉันได้รับข้อผิดพลาดเดียวกันแม้ว่าจะเพิ่มความแตกต่างกันไปแล้วจนกว่าฉันจะจัดเรียงการรวมการสืบค้นภายในของฉันใหม่ดังนั้นฉันจึงเริ่มต้นด้วยตารางที่ได้รับมากกว่าหนึ่งแถวกลับมาและภายในเข้าร่วมจากที่นั่น ... ถ้าเป็นเช่นนั้น มีเหตุผล.
jinglesthula

40

คุณอาจพยายามอัปเดตแถวเดียวกันของตารางเป้าหมายหลายครั้ง ฉันเพิ่งพบปัญหาเดียวกันนี้ในคำสั่งผสานที่ฉันพัฒนา ตรวจสอบให้แน่ใจว่าการอัปเดตของคุณไม่ได้สัมผัสกับบันทึกเดียวกันมากกว่าหนึ่งครั้งในการดำเนินการผสาน


1
+1 ขอบคุณสิ่งนี้เพิ่งเกิดขึ้นกับฉันบนตารางเป้าหมายที่มีรายการซ้ำจำนวนเล็กน้อย (อย่างน้อยก็ขึ้นอยู่กับคีย์ที่ใช้ในการผสาน)
tbone

6

วิธีแก้ไขข้อผิดพลาด ORA-30926 (รหัสเอกสาร 471956.1)

1) ระบุคำสั่งที่ล้มเหลว

แก้ไขเหตุการณ์ชุดเซสชัน '30926 ชื่อการติดตาม errorstack ระดับ 3';

หรือ

แก้ไขการตั้งค่าระบบเหตุการณ์ '30926 ชื่อการติดตาม errorstack off';

และดูไฟล์. trc ใน UDUMP เมื่อเกิดขึ้น

2) เมื่อพบคำสั่ง SQL ให้ตรวจสอบว่าถูกต้องหรือไม่ (อาจใช้อธิบายแผนหรือ tkprof เพื่อตรวจสอบแผนการดำเนินการสืบค้น) และวิเคราะห์หรือคำนวณสถิติในตารางที่เกี่ยวข้องหากยังไม่ได้ดำเนินการเมื่อเร็ว ๆ นี้ การสร้างดัชนีใหม่ (หรือทิ้ง / สร้างใหม่) อาจช่วยได้เช่นกัน

3.1) คำสั่ง SQL เป็นการผสานหรือไม่ ประเมินข้อมูลที่ส่งคืนโดย USING clause เพื่อให้แน่ใจว่าไม่มีค่าที่ซ้ำกันในการรวม แก้ไขคำสั่ง merge เพื่อรวมกำหนดโดยที่ clause

3.2) นี่คือคำสั่ง UPDATE ผ่านมุมมองหรือไม่? หากเป็นเช่นนั้นให้ลองใส่ผลลัพธ์มุมมองลงในตารางแล้วลองอัปเดตตารางโดยตรง

3.3) มีทริกเกอร์บนโต๊ะหรือไม่? ลองปิดการใช้งานเพื่อดูว่ายังล้มเหลวหรือไม่

3.4) คำสั่งมีมุมมองที่ไม่สามารถผสานได้ใน 'IN-Subquery' หรือไม่? ซึ่งอาจส่งผลให้มีการส่งคืนแถวที่ซ้ำกันหากแบบสอบถามมีอนุประโยค "FOR UPDATE" ดู Bug 2681037

3.5) ตารางมีคอลัมน์ที่ไม่ได้ใช้หรือไม่? การทิ้งสิ่งเหล่านี้อาจป้องกันข้อผิดพลาดได้

4) หากการปรับเปลี่ยน SQL ไม่สามารถแก้ไขข้อผิดพลาดได้ปัญหาอาจอยู่ที่ตารางโดยเฉพาะอย่างยิ่งหากมีแถวที่ถูกล่ามโซ่ 4.1) เรียกใช้คำสั่ง 'ANALYZE TABLE VALIDATE STRUCTURE CASCADE' บนตารางทั้งหมดที่ใช้ใน SQL เพื่อดูว่ามีความเสียหายในตารางหรือดัชนีหรือไม่ 4.2) ตรวจหาและกำจัดแถวที่ถูกล่ามโซ่หรือย้ายข้อมูลบนโต๊ะ มีหลายวิธีในการย่อขนาดเช่นการตั้งค่า PCTFREE ที่ถูกต้อง ใช้หมายเหตุ 122020.1 - การเชื่อมโยงแถวและการโยกย้าย 4.3) หากตารางมีการจัดระเบียบดัชนีเพิ่มเติมโปรดดู: หมายเหตุ 102932.1 - การตรวจสอบแถวโซ่บน IOT


5

มีข้อผิดพลาดในวันนี้ใน 12c และไม่มีคำตอบใดที่มีอยู่พอดี (ไม่มีรายการที่ซ้ำกันไม่มีนิพจน์ที่ไม่ได้กำหนดในส่วนคำสั่ง WHERE) กรณีของฉันเกี่ยวข้องกับสาเหตุอื่น ๆ ที่เป็นไปได้ของข้อผิดพลาดตามข้อความของ Oracle (เน้นด้านล่าง):

ORA-30926: ไม่สามารถรับชุดแถวที่คงที่ในตารางต้นทางได้
สาเหตุ: ไม่สามารถหาชุดแถวที่เสถียรได้เนื่องจากกิจกรรม dml ขนาดใหญ่หรือไม่ได้กำหนดโดยที่อนุประโยค

การผสานเป็นส่วนหนึ่งของชุดงานที่ใหญ่ขึ้นและถูกดำเนินการบนฐานข้อมูลสดที่มีผู้ใช้พร้อมกันจำนวนมาก ไม่จำเป็นต้องเปลี่ยนคำสั่ง ฉันเพิ่งทำธุรกรรมก่อนการผสานจากนั้นเรียกใช้การผสานแยกจากกันและตกลงอีกครั้ง ดังนั้นจึงพบวิธีแก้ปัญหาในการดำเนินการที่แนะนำของข้อความ:

การดำเนินการ: ลบใด ๆ ที่ไม่ได้กำหนดไว้ที่ส่วนคำสั่งและออก dmlใหม่


ฉันได้รับข้อความแสดงข้อผิดพลาดที่ดำเนินการนำเข้า DataPump ผ่านเครือข่าย (โดยใช้NETWORK_LINKพารามิเตอร์ที่เชื่อมต่อโดยตรงกับฐานข้อมูลต้นทาง) ในระหว่างขั้นตอนการรวบรวมสถิติและบันทึกที่ไฮไลต์ของคุณอาจอธิบายได้ โชคดีที่สถิติได้รับผลกระทบ
Mark Stewart

1
SQL Error: ORA-30926: unable to get a stable set of rows in the source tables
30926. 00000 -  "unable to get a stable set of rows in the source tables"
*Cause:    A stable set of rows could not be got because of large dml
           activity or a non-deterministic where clause.
*Action:   Remove any non-deterministic where clauses and reissue the dml.

ข้อผิดพลาดนี้เกิดขึ้นสำหรับฉันเนื่องจากมีระเบียนที่ซ้ำกัน (16K)

ฉันพยายามด้วยเอกลักษณ์มันได้ผล

แต่อีกครั้งเมื่อฉันลองผสานโดยไม่มีปัญหาเดียวกันเกิดขึ้นครั้งที่สองมันเกิดจากการกระทำ

หลังจากผสานหากไม่ได้กระทำข้อผิดพลาดเดียวกันจะแสดงขึ้น

โดยไม่ซ้ำกัน Query จะทำงานหากให้การกระทำหลังจากการผสานแต่ละครั้ง


-1

คำชี้แจงเพิ่มเติมเกี่ยวกับการใช้ DISTINCT เพื่อแก้ไขข้อผิดพลาด ORA-30926 ในกรณีทั่วไป:

คุณต้องให้แน่ใจว่าชุดของข้อมูลที่ระบุโดยใช้ () ประโยคไม่มีค่าที่ซ้ำกันของคอลัมน์เข้าร่วมคือคอลัมน์ใน ON () ข้อ

ในตัวอย่างของ OP ที่ประโยค USING เลือกเฉพาะคีย์ก็เพียงพอแล้วที่จะเพิ่ม DISTINCT ให้กับประโยค USING อย่างไรก็ตามในกรณีทั่วไปคำสั่ง USING อาจเลือกคอลัมน์คีย์ร่วมกันเพื่อจับคู่และคอลัมน์แอตทริบิวต์ที่จะใช้ในส่วนคำสั่ง UPDATE ... SET ดังนั้นในกรณีทั่วไปการเพิ่ม DISTINCT ในประโยค USING จะยังคงอนุญาตให้มีแถวการอัปเดตที่แตกต่างกันสำหรับคีย์เดียวกันซึ่งในกรณีนี้คุณจะยังคงได้รับข้อผิดพลาด ORA-30926

นี่คือรายละเอียดของคำตอบของ DCookie และข้อ 3.1 ในคำตอบของ Tagar ซึ่งจากประสบการณ์ของฉันอาจไม่ชัดเจนในทันที

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.