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
อ่านเพิ่มเติม