Oracle: ORA-31603

Error ORA-31603 มักเกิดขึ้นเมื่อใช้แพ็คเกจ DBMS_METADATA.GET_DDL เพื่อดึง SQL สำหรับสร้าง Object แต่ระบบหาตัวตนของ Object นั้นไม่เจอใน Schema ที่ระบุครับ

สาเหตุส่วนใหญ่ไม่ได้แปลว่าไม่มี Object นั้นอยู่จริงเสมอไป แต่อาจเกิดจาก “เส้นผมบังภูเขา” ในเรื่องของสิทธิ์หรือตัวพิมพ์เล็ก-ใหญ่ ลองเช็กตามลำดับนี้ดูครับ


ตรวจสอบ “ตัวพิมพ์ใหญ่”

Oracle เก็บชื่อ Object ใน Dictionary เป็น ตัวพิมพ์ใหญ่ เสมอ เว้นแต่คุณจะสร้างโดยใส่เครื่องหมายคำพูดคร่อมชื่อไว้

  • ผิด:
    SELECT DBMS_METADATA.GET_DDL ('TABLE', 'my_table') FROM DUAL
  • ถูก:
    SELECT DBMS_METADATA.GET_DDL ('TABLE', 'MY_TABLE') FROM DUAL

ตรวจสอบสิทธิ์

การจะดึง DDL ของคนอื่นได้ คุณต้องมีสิทธิ์สูงพอ หากคุณพยายามดึง DDL ของ Schema อื่นโดยไม่มีสิทธิ์ SELECT_CATALOG_ROLE หรือ SELECT ANY DICTIONARY ระบบจะฟ้อง Error นี้แทนที่จะบอกว่า “Permission Denied” เพื่อความปลอดภัย

  • วิธีแก้: ลองรันด้วย User ที่เป็นเจ้าของ Object นั้นโดยตรง หรือใช้ User ที่มีสิทธิ์ระดับ DBA
  • เช็กสิทธิ์ปัจจุบัน:
    SELECT * FROM SESSION_ROLES WHERE ROLE = 'SELECT_CATALOG_ROLE'

ตรวจสอบชื่อ Schema และ Object Type

ตรวจสอบให้แน่ใจว่าระบุ OBJECT_TYPE ให้ตรงกับประเภทของมันจริง ๆ

Query เช็กสถานะ: ลองค้นหาใน Dictionary ก่อนว่ามันอยู่ตรงไหนแน่

SELECT owner, object_name, object_type FROM all_objects WHERE object_name = 'YOUR_OBJECT_NAME';

กรณีใช้ผ่าน Database Link

หากคุณกำลังดึงข้อมูลข้าม Database Link บางครั้ง DBMS_METADATA จะทำงานไม่ได้โดยตรง ต้องรันคำสั่งที่ฝั่งต้นทาง เท่านั้น


สรุปวิธีแก้เร็ว ๆ

ลองรันคำสั่งโดยใช้ตัวพิมพ์ใหญ่ทั้งหมดและระบุ Owner ให้ชัดเจน

-- รูปแบบ: DBMS_METADATA.GET_DDL ('ประเภท', 'ชื่อวัตถุ', 'เจ้าของ') SELECT DBMS_METADATA.GET_DDL ('TABLE', 'EMPLOYEES', 'HR') FROM DUAL

อ่านเพิ่มเติม