[DB2] Restrictive Database ทำให้เกิด Error CLI0125E Function sequence error. SQLSTATE=S1010

เนื่องจากทีมที่ได้เข้ามาทำ Hardening ทีมก่อนหน้าได้เปิด Option การสร้าง Database แบบ Restrictive ครับ ทำให้ Application เดี้ยงกับเป็นแถบครับ ก่อนทีจะแก้ปัญหาเราต้องมารู้จักกันก่อนครับ ว่าเจ้า Restrictive มัน คือ อะไร

Restrictive Database

  • Database ที่มีการจำกัดสิทธิของ Publish ออกหมดเลยครับ
  • หากสงสัยอะไร สามารถอ่าน Blog ของผมเพิ่มเติมได้เลยครับ

มาดูปัญหาของฝั่ง Application ดีกว่าครับ

  • Application เป็นโปรแกรมที่เก่าอยู่พอสมควรครับ ใช้ ADODB เป็นเทคโนโลยีในการเชื่อมต่อ (VB6 + RecordSet) ครับ
  • การเชื่อมต่อกับฐานข้อมูลใช้เทคโนโลยี ODBC หรือ Open Database Connectivity เป็น API กลางที่ทาง Microsoft เตรียมไว้ให้กับผู้พัฒนา Database ค่ายต่างๆมาเขียนวิธีการเชื่อมต่อกับฐานข้อมูลของตัวเองครับ

ปัญหาที่เกิดขึ้น มัน คือ อะไรกันนะ ?

  • เมื่อลองเปิด Application ขึ้นพบหน้าจอแจ้งเตือน

[IBM][CLI Driver] CLI0125E Function sequence error. SQLSTATE=S1010 

Error ครอบจักรวาล เหมือนเคส Else
  • ซึ่งพอไปดู Doc DB2 แล้ว โอโห้ Error เดียวครอบจักรวาลเลยครับ
  • จริงๆแล้ว Error [IBM][CLI Driver] CLI0125E Function sequence error. SQLSTATE=S1010 มันเป็นของ ODBC ครับ ไม่ใช่ของ DB2 ครับ

แนวทางการหาสาเหตุหละ ?

  • วิธีแรก เปิด Trace Log ที่ตัว DB2 Client ครับ ได้ Log มานะ แต่มันไม่ค่อยได้ช่วยเท่าไหร่ เดี๋ยวไว้ผมจะเขียน Blog แยกอีกตอนครับ
  • วิธีที่สอง ลองย้อนกลับไปถึงเรื่อง ODBC ครับ ODBC ของ Microsoft จากการลองค้นหาดูตัว ODBC มี Trace Log ของมันครับ ซึ่งจะช่วยให้เราตรวจสอบบันทึกของการทำงานที่แปลกๆกับ Application ของเราที่ใช้ ODBC ในการเชื่อมต่อฐานข้อมูลได้ครับ

ขั้นตอนการใช้งาน ODBC Trace Log คือ อะไร

  • ตรวจสอบก่อนว่า Application ที่กำลังตรวจสอบกำหนด ODBC ได้ถูกต้อง
  • ตรวจสอบก่อนครับว่าใช้งาน ODBC แบบ 32 bits หรือ 64 bits ครับ เพื่อเปิดหน้าจอ ODBC Data Sources Administrator
    • 32 bits : %windir%\syswow64\odbcad32.exe
    • 64 bits : %windir%\system32\odbcad32.exe
  • มาที่ Tab Tracing จากนั้นกำหนดค่า ดังนี้
    • หมายเลข 1 ติ๊กเลิอกครับ เพื่อให้มันตรวจจับการตั้งค่าให้เรียบร้อย
    • หมายเลข 2 กำหนด Path ที่ให้เก็บตัว ODBC Trace Log
    • หมายเลข 3 เมื่อพร้อมแล้วกดปุ่ม Start Tracing Now ครับ
  • เมื่อตั้งค่าเสร็จเรียบร้อยให้กลับไปเปิด Application ที่มีปัญหาขึ้นมาครับ และทำขั้นตอนซ้ำอีกรอบจนได้ Error ขึ้นมา
  • กลับมาที่หน้าจอ ODBC Data Sources Administrator Tab Tracing และกดปุ่ม Stop Tracing Now ครับ
  • จากนั้นเข้าไปดูที่ ODBC Trace Log ในที่นี้ผมกำหนดไว้ที่ Path E:\Temp ครับ

วิเคราะห์ ODBC Trace Log ค้นหาความจริง

  • เปิดไฟล์ Log ขึ้นมาครับ จากนั้นลองค้นหาข้อ Keyword ที่เกี่ยวข้องกับฐานข้อมูลดูครับ เช่น DB2 / Oracle เป็นต้นครับ
  • อย่างผมใช้ Keyword DB2 และเจอคำที่ช่วยให้เล็กลงอีกอย่าง DB2/LINUXX8664
  • ตอนนี้เราได้ Error จริงๆของ DB2 มาแล้วครับ พอได้ Error นี้ ก็สามารถเอาไปค้นหาคำตอบได้ต่อครับ
  • หลังจากนั้น Try & Error ลองแก้ เปิด Application ทดสอบ และวนกลับมาแก้ไขจนทำงานได้ครบทุกเคสครับ

Script สุดท้ายครับ

GRANT EXECUTE on PROCEDURE SYSIBM.SQLPRIMARYKEYS TO user pingkunga;
GRANT EXECUTE on PROCEDURE SYSIBM.SQLSTATISTICS TO user pingkunga;
GRANT EXECUTE ON PROCEDURE SYSIBM.SQLGETTYPEINFO TO user pingkunga;
GRANT EXECUTE ON PROCEDURE SYSIBM.SQLTABLES TO user pingkunga;
GRANT EXECUTE ON PROCEDURE SYSIBM.SQLCOLUMNS TO user pingkunga;
GRANT EXECUTE ON PROCEDURE SYSIBM.SQLCAMESSAGECCSID TO user pingkunga;

GRANT EXECUTE on package NULLID.SYSSH200 TO user pingkunga;
GRANT EXECUTE on package NULLID.SQLC2O26 to role ROLE_REGULAR_USERS;

GRANT SELECT ON SYSIBM.SQLPRIMARYKEYS  TO user pingkunga;
GRANT SELECT ON SYSIBM.SQLSTATISTICS  TO user pingkunga;
GRANT SELECT ON SYSIBM.SQLTABLES TO user pingkunga;
GRANT SELECT ON SYSIBM.SYSTABLES TO user pingkunga;
GRANT SELECT ON SYSIBM.SQLTABLETYPES TO user pingkunga;
GRANT SELECT ON SYSIBM.SQLTABLEPRIVILEGES  TO user pingkunga;
GRANT SELECT ON SYSIBM.SYSCOLUMNS TO user pingkunga;
GRANT SELECT ON SYSIBM.SQLSPECIALCOLUMNS  TO user pingkunga;
GRANT SELECT ON SYSIBM.SQLCOLPRIVILEGES TO user pingkunga;
GRANT SELECT ON SYSIBM.SYSDUMMY1  TO user pingkunga;

GRANT SELECT ON SYSIBM.SQLFOREIGNKEYS  TO user pingkunga;
GRANT SELECT ON SYSIBM.SYSINDEXES  TO user pingkunga;
GRANT SELECT ON SYSIBM.SQLPROCEDURES  TO user pingkunga;
GRANT SELECT ON SYSIBM.SQLPROCEDURECOLS  TO user pingkunga;
GRANT SELECT ON SYSIBM.SYSROUTINES  TO user pingkunga;
GRANT SELECT ON SYSIBM.SYSROUTINEPARMS  TO user pingkunga;
GRANT SELECT ON SYSIBM.SQLTYPEINFO  TO user pingkunga;
GRANT SELECT ON SYSIBM.SQLUDTS  TO user pingkunga;
GRANT SELECT ON SYSIBM.SQLSCHEMAS  TO user pingkunga;
GRANT SELECT ON SYSIBM.SYSRELS  TO user pingkunga;
GRANT SELECT ON SYSIBM.SYSKEYCOLUSE  TO user pingkunga;
GRANT SELECT ON SYSIBM.SYSTABCONST  TO user pingkunga;
GRANT SELECT ON SYSIBM.SYSDATATYPES  TO user pingkunga;
GRANT SELECT ON SYSIBM.SQLSTATISTICS  TO user pingkunga;

กว่าจะแก้ได้ก็เหนื่อยเลยครับ ใช่เวลาแก้ไขกันานพอสมควรครับ แก้ไขที่ละจุด อย่างเคสนี้ของ DB2 ถ้ามีคู่มือแนะนำดีๆจะดีมากครับ