Fixed : KU$_RADM_FPTM_VIEW in invalid status

ฐานข้อมูลที่จะพบปัญหานี้ Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 OS เป็น CentOS 7.3 หรือ Oracle Enterprise Linux 7.3 ปัญหานี้ข้อสำคัญทำให้ export ข้อมูลไม่ได้ คือไม่สามารถสำรองข้อมูลได้ เข้าระบบด้วยผู้ใช้ oracle สร้างแฟ้ม fix.sql ด้วยคำสั่ง cat >>fix.sql<<EOF CREATE OR REPLACE NONEDITIONABLE TYPE “SYS”.”KU$_RADM_FPTM_T” as object ( vers_major char(1), /* UDT major version # */ vers_minor char(1), /* UDT minor version # */ numbercol number, /* number */ binfloatcol binary_float, /* binary float */ bindoublecol binary_double, /* binary double */ charcol char(1), /* fixed-size character */ varcharcol varchar2(1), /* variable-size character */ ncharcol nchar(1), /* fixed-size national character */ nvarcharcol nvarchar2(1), /* variable-size national character */ datecol date, /* date */ ts_col timestamp, /* timestamp */ tswtz_col timestamp with time zone, /* timestamp with time zone */ fpver number /* version of default fixed point values */ ) / CREATE OR REPLACE FORCE NONEDITIONABLE VIEW “SYS”.”KU$_RADM_FPTM_VIEW” OF “SYS”.”KU$_RADM_FPTM_T” WITH OBJECT IDENTIFIER (fpver) AS select ‘1’,’0′, numbercol, binfloatcol, bindoublecol, charcol, varcharcol, ncharcol, nvarcharcol, datecol,ts_col,tswtz_col, fpver from sys.radm_fptm$ where fpver=1 / EOF เชื่อมต่อกับฐานข้อมูลด้วย sqlplus ด้วยบัญชีผู้ใช้ / as sysdba ที่ prompt SQL> พิมพ์คำสั่ง @/home/oracle/fix.sql ก็จะแก้ปัญหาได้ จบ ขอให้สนุก ที่มา เว็บโดนปิดไปแล้ว

Read More »

การเรียกดูรายการ object ในฐานข้อมูล Oracle

คำสั่งที่ใช้ในการเรียกดู รายการ object ในฐานข้อมูล Oracle การเรียกดูรายการ object ทั้งหมดในฐานข้อมูล Oracle (เช่น table, view ฯลฯ)  สามารถเรียกดูได้จาก view ที่ชื่อว่า ALL_OBJECTS  ตัวอย่างคำสั่งคือที่ใช้เรียกดูคือ   SELECT * FROM ALL_OBJECTS;   โดยคำสั่งนี้จะแสดงรายการ object ทั้งหมดที่มี   แต่ในการใช้งานส่วนใหญ่ อาจจะต้องการเจาะจงดูแค่บางเงื่อนไข เช่น ต้องการดูรายการ table ทั้งหมด โดยเจาะจงแค่ schema ใด schema  หนึ่งเท่านั้น  ซึ่งสามารถใช้เงื่อนไขจากฟีลด์ต่อไปนี้ คือ OBJECT_TYPE เป็นการเรียกดูตามเงื่อนไขของประเภท object เช่น หากต้องการดูเฉพาะ table จะใช้เงื่อนไขเป็น  WHERE OBJECT_TYPE = ‘TABLE’ OWNER เป็นการเรียกดูเฉพาะเจาะจง schema ใด schema  หนึ่ง เช่น ต้องการเรียกดูข้อมูลจาก schema ชื่อ SCOTT จะใช้เงื่อนไขเป็น WHERE OWNER = ‘SCOTT’ ตัวอย่างคำสั่งเต็ม ๆ กรณีที่ต้องการเรียกดูเฉพาะ table ทั้งหมดที่อยู่ใน schema ที่ชื่อ SCOTT SELECT * FROM ALL_OBJECTS WHERE OBJECT_TYPE=’TABLE’ AND OWNER=’SCOTT’;   ตัวอย่างการนำไปใช้ประโยชน์ เพื่อให้เห็นภาพการนำไปใช้งานจริง จึงขอยกตัวอย่างที่เคยใช้งาน คือ การสร้างสคริปต์คำสั่ง sql ที่อ้างอิงชื่อ table ที่อยู่ใน schema ใด schema หนึ่ง โดยในที่นี้จะยกตัวอย่างการ grant สิทธิ์ในการเข้าถึงข้อมูลของ schema หนึ่งไปให้กับอีก schema หนึ่ง ที่มาที่ไปคือ ในบางครั้ง เราต้องการ grant สิทธิ์ในการเข้าถึงข้อมูลของ schema หนึ่งไปให้กับอีก schema หนึ่ง เช่น ต้องการ grant สิทธิ์การเรียกดูข้อมูลใน table ชื่อ TABLE01 ของ schema ที่ชื่อ SCHEMA01 ให้ schema ที่ชื่อ SCHEMA02 สามารถเรียกดูข้อมูลได้ คำสั่งที่ใช้ในการ grant คือGRANT SELECT ON SCHEMA01.TABLE01 TO SCHEMA02; แต่หากต้องการ grant หลาย ๆ  table ก็ต้องพิมพ์คำสั่งเหล่านี้ทีละคำสั่งซ้ำๆ ไปจนครบตามชื่อ talbe ที่ต้องการ grant ซึ่งถ้า table ที่ต้องการ grant มีเป็นจำนวนมากก็จะยิ่งใช้เวลามากยิ่งขึ้น และอีกปัญหาคือ มีโอกาสพิมพ์ชื่อ table ผิด เทคนิคในการสร้างสคริปต์เพื่อช่วยให้การทำงานรวดเร็วขึ้นจะมีรูปแบบดังนี้คือSELECT ‘GRANT SELECT ON OWNER_SCHEMA.’ || OBJECT_NAME || ‘ TO OTHER_SCHEMA;’ FROM ALL_OBJECTS WHERE OBJECT_TYPE = ‘TABLE’; เมื่อ OWNER_SCHEMA คือชื่อของ schema ที่เป็นเจ้าของ table OBJECT_NAME คือชื่อฟีลด์ที่อยู่ใน ALL_OBJECTS โดยเป็นข้อมูลของชื่อ object ซึ่งกรณีนี้คือชื่อของ table นั่นเอง OTHER_SCHEMA คือชื่อของ schema ที่ได้รับการ grant สิทธิ์ให้เรียกดูข้อมูลใน table ของ OWNER_SCHEMA WHERE OBJECT_TYPE = ‘TABLE’ เป็นการระบุเงื่อนไขว่าต้องการ object ที่เป็น table เท่านั้น ผลลัพธ์ที่ได้คือ GRANT SELECT ON OWNER_SCHEMA.TABLE01 TO OTHER_SCHEMA; GRANT SELECT ON OWNER_SCHEMA.TABLE02

Read More »

Oracle: retrieve top n records for each group

วิธีการเขียน Query เพื่อดึงข้อมูลข้อมูลสูงสุดหรือต่ำสุด N ลำดับแรกของแต่ละกลุ่มออกมาจากตาราง สมมติว่าเรามีข้อมูลคะแนนภาษาอังกฤษของนักศึกษาใหม่ซึ่งประกอบด้วย 5 ฟิลด์ข้อมูลดังตัวอย่างข้างล่าง ข้อมูล: ตาราง TEST_NEW_STUDENT เป็นตัวอย่างข้อมูลคะแนนภาษาอังกฤษของนักศึกษาใหม่จำนวน 773 รายการ โจทย์: ต้องการดึงข้อมูลนักศึกษาที่ได้คะแนนภาษาอังกฤษสูงสุดแยกตามคณะจากข้อมูลคะแนนภาษาอังกฤษของนักศึกษาใหม่จำนวน 773 รายการนี้ เริ่มต้นด้วย query ดังนี้ SELECT a.*, ROW_NUMBER () OVER (PARTITION BY fac_id ORDER BY eng_score DESC) AS val_row_number FROM test_new_student a จุดสำคัญของ query ข้างต้นก็คือฟังก์ชัน ROW_NUMBER ซึ่งเป็นฟังก์ชันที่จะให้เลขบรรทัดของผลลัพธ์ออกมาตามการจัดกลุ่มข้อมูลหรือการเรียงลำดับที่เรากำหนดไว้ด้วยคำสั่ง OVER, PARTITION BY และ ORDER BY ที่ตามมา จากตัวอย่างข้างต้นหมายความว่า เรากำลัง Select * จากตาราง TEST_NEW_STUDENT พร้อมกับดึงเลข ROW_NUMBER ออกมา โดยเป็นเลขบรรทัดที่ให้แบ่งกลุ่มด้วยคณะ และให้เรียงลำดับด้วยคะแนนภาษาอังกฤษจากมากไปน้อย ซึ่งผลที่ได้จะเป็นดังนี้ สังเกตที่ฟิลด์ VAL_ROW_NUMBER จะเห็นว่ามันแสดงตามอันดับของคะแนนภาษาอังกฤษ และถูกแบ่งตามคณะอย่างเรียบร้อย แค่นี้เราก็สามารถที่จะ select เอา Top ที่เท่าไหร่ของแต่ละกลุ่มได้แล้ว โดยเลือกเอา VAL_ROW_NUMBER ที่ต้องการ ซึ่งสามารถทำได้โดยเขียน select…where ซ้อน query ข้างต้นเข้าไปอีกทีดังนี้ SELECT * FROM (SELECT a.*, ROW_NUMBER () OVER (PARTITION BY fac_id ORDER BY eng_score DESC) AS val_row_number FROM test_new_student a) WHERE val_row_number <= 1; ผลลัพธ์: สรุปจากความต้องการที่ตั้งไว้ เราสามารถแก้ได้โดยใช้ Window Function ซึ่งมันสามารถหาเลขลำดับบางอย่างภายในกลุ่มข้อมูลออกมาให้ได้รูปแบบทั่วไปของ query คือ 1 SELECT *, 2 WFUNCTION OVER (PARTITION BY GROUP_FIELDS ORDER BY ORDER_FIELDS) n 3 FROM SOURCE โดยที่ SOURCE คือตัวข้อมูล WFUNCTION  หมายถึง Window Function ตัวอย่างที่เราเลือกใช้คือ ROW_NUMBER() GROUP_FIELDS คือรายการฟิลด์ที่จะแบ่งกลุ่ม เขียนเหมือนตอนที่เราจะ group by สามารถแบ่งด้วยหลายฟิลด์ก็ได้ ORDER_FIELDS คือรายการฟิลด์ที่ใช้เรียงลำดับ, สามารถเรียงด้วยหลายฟิลด์ก็ได้, ใส่ ASC หรือ DESC ได้เหมือนคำสั่ง order by ปกติเราไม่จำเป็นต้องใส่ทั้ง partition by และ order by อาจจะใส่แค่อันใดอันหนึ่ง แล้วแต่ว่าต้องการแบ่งกลุ่มหรือเรียงลำดับหรือไม่ n เป็นชื่อ alias ของผลลัพธ์ จะตั้งชื่ออย่างไรก็ได้ เมื่อเราได้เลขลำดับ n ของแต่ละกลุ่มออกมาแล้ว ทีนี้จะเอาไปหา Top N หรือพลิกแพลงยังไง ก็แล้วแต่จะ query ออกมา

Read More »

Oracle: retrieve top n records from a query

Top-N queries เป็นวิธีการดึงข้อมูลสูงสุดหรือต่ำสุด N ลำดับแรกออกมาจากตาราง โดยวิธีการดึงข้อมูลแบบ Top-N นั้นมีได้หลายวิธี แต่ในบทความนี้จะนำเสนอวิธีการดึงข้อมูลแบบ Top-N records เพียง 3 วิธีการดังนี้ 1. Inline View and ROWNUM 2. WITH Clause and ROWNUM 3. ROW_NUMBER   สมมติว่าเรามีข้อมูลคะแนนภาษาอังกฤษของนักศึกษาใหม่ซึ่งประกอบด้วย 5 ฟิลด์ข้อมูลดังตัวอย่างข้างล่าง ข้อมูล: ตาราง TEST_NEW_STUDENT เป็นตัวอย่างข้อมูลคะแนนภาษาอังกฤษของนักศึกษาใหม่จำนวน 773 รายการ โจทย์: ต้องการดึงข้อมูลนักศึกษาที่ได้คะแนนภาษาอังกฤษสูงสุด 5 อันดันแรกจากข้อมูลคะแนนภาษาอังกฤษของนักศึกษาใหม่จำนวน 773 รายการนี้   เริ่มต้น Top-N query ตามลำดับเพื่อแก้โจทย์กันค่ะ Inline View and ROWNUM Classic Top-N style query SELECT a.*,rownum FROM (SELECT * FROM test_new_student ORDER BY eng_score desc) a WHERE ROWNUM <= 5; ผลลัพธ์: • จากผลลัพธ์ที่ได้ข้อมูลจะถูกจัดเรียงจากคะแนนจากมากไปน้อยก่อนด้วย ORDER BY clause และหลังจากนั้นก็จะจำกัดจำนวนข้อมูลที่ต้องการด้วย ROWNUM • Pseudocolumn ROWNUM เป็นค่าตัวเลขแสดงลำดับที่ของการดึงข้อมูลจากตาราง • กรณีที่ต้องการข้อมูลคะแนนภาษาอังกฤษต่ำสุด ใส่ ASC แทน DESC ตรง ORDER BY clause   WITH Clause and ROWNUM จากตัวอย่างข้างต้นเรายังสามารถเขียน query ด้วย WITH clause แทนที่ inline view ได้ดังนี้ WITH ordered_query AS (SELECT * FROM test_new_student ORDER BY eng_score desc) SELECT ordered_query.*,rownum FROM ordered_query WHERE rownum <= 5;   ROW_NUMBER ฟังก์ชัน ROW_NUMBER เป็นฟังก์ชันที่กำหนดค่าลำดับของข้อมูลที่จัดเรียงตามข้อมูลที่กำหนดไว้ใน order_by_clause โดยจะมีค่าเริ่มต้นเท่ากับ 1 โดยเราจะมีวิธีการเขียน query ได้ดังนี้ SELECT * FROM (SELECT a.*, row_number() OVER (ORDER BY eng_score DESC) AS val_row_number FROM test_new_student a) WHERE val_row_number <= 5; ผลลัพธ์: สังเกตที่ฟิลด์ VAL_ROW_NUMBER จะเห็นว่ามันแสดงตามอันดับของคะแนนภาษาอังกฤษแล้ว แค่นี้เราก็สามารถที่จะ select เอา Top ที่เท่าไหร่ได้แล้ว โดยเลือกเอา VAL_ROW_NUMBER ที่ต้องการ

Read More »

Oracle MySQL Cluster :- The shared-nothing architecture (Manual Installation)

สิ่งที่ต้องเตรียม ได้แก่ Ubuntu Server 16.04 (รุ่น x86_64 architecture) จำนวนอย่างน้อย 4 เครื่อง (แต่ควรอย่างน้อย 6 เครื่อง), IP Address 4 IP, Software MySQL Cluster โหลดที่ https://edelivery.oracle.com/ (ต้องสมัครสมาชิกให้เรียบร้อยก่อน) ใช้คำค้นว่า MySQL Cluster (จะมีรุ่น 7.5.5 ให้โหลด) โดยไฟล์ที่ใช้งานชื่อว่า V840854-01.zip MySQL Cluster 7.5.5 TAR for Generic Linux (glibc2.5) x86 (64bit) 4 เครื่องประกอบด้วยอะไรบ้าง 2 x data nodes เปลี่ยน IP ให้ตรงกับที่ใช้งาน 192.168.106.32  Data-node1 192.168.106.33  Data-node2 1 x SQL/NoSQL Application Node 192.168.106.42  SQL-Node 1 x Management Node 192.168.106.40  Management-node เริ่มที่ Management Node ssh 192.168.106.40 -l sudo_user (user ที่เรียกใช้คำสั่ง sudo ได้) คลายแฟ้ม V840854-01.zip ด้วยคำสั่ง unzip V840854-01.zip (อาจต้องติดตั้งเพิ่มเติมด้วยคำสั่ง sudo apt install unzip) จะได้แฟ้ม  mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64.tar.gz คลายแฟ้ม mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64.tar.gz ด้วยคำสั่ง tar zxvf mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64.tar.gz เปลี่่ยนชื่อ mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64 เป็น mysql mv mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64 mysql คัดลอกแฟ้ม mysql/bin/ndb_mgmd และ mysql/bin/ndb_mgm ไปไว้ที่ /usr/local/bin cp mysql/bin/ndb_mgm* /usr/local/bin/ สร้างโฟลเดอร์ /var/lib/mysql-cluster และสร้างแฟ้ม /var/lib/mysql-cluster/config.ini sudo mkdir -p /var/lib/mysql-cluster/ เพื่อเป็นการบอก Management node ว่า Data Node และ SQL Node มีใครบ้าง ให้สร้าง config.ini ไว้ที่ /var/lib/mysql-cluster ด้วยคำสั่ง cat<< EOF | sudo tee /var/lib/mysql-cluster/config.ini เพิ่มข้อความต่อไปนี้ลงไป [ndbd default] NoOfReplicas=2 DataMemory=80M IndexMemory=18M [mysqld default] [ndb_mgmd default] [tcp default]# Cluster Control / Management node [ndb_mgmd] hostname=192.168.106.40# Data Node 1 [ndbd] hostname=192.168.106.32 DataDir= /var/lib/mysql-cluster# Data Node 2 [ndbd] HostName=192.168.106.33 DataDir=/var/lib/mysql-cluster# SQL Node [mysqld] hostname=192.168.106.42 # If you to add new SQL Node [mysqld] EOF เพิ่มข้อความต่อไปนี้ในแฟ้ม /etc/rc.local /var/lib/mysql-cluster/config.ini –configdir=/var/lib/mysql-cluster/ โดยเพิ่มให้อยู่บรรทัดก่อนคำว่า exit 0 ตัวอย่าง /etc/rc.local #!/bin/sh -e # # rc.local #

Read More »