วันอังคารที่ 22 กันยายน พ.ศ. 2552

สร้าง Table พักด้วย Global Temporary Table

การพัฒนาแอพพลิเคชั่นบางโปรแกรมที่มีความซับซ้อนมาก ๆ อาจจะมีความจำเป็นที่ต้องใช้ Table ชั่วคราวเพื่อพักข้อมูลที่ได้จากการปะมวลผลไว้ก่อน แล้วจึงนำข้อมูลใน Table พักนั้นไปประมวลผลทำงานต่อจนจบกระบวนการของโปรแกรม หลังจากนั้นเราก็จะทำการลบข้อมูลใน Table พักชั่วคราวนั้นทิ้งไปเพื่อไม่ให้ข้อมูลเหล่านั้นเป็นขยะค้างอยู่ในระบบ หากคิดกันแบบง่าย ๆ ก็ทำได้โดยสร้าง Table ขึ้นมารองรับและเมื่อใช้งานเสร็จก็ลบข้อมูลทิ้งไป แต่ในชีวิตจริงแล้วแอพพลิเคชั่นที่ใช้งานจะมีผู้ใช้หลายคนทำงานพร้อม ๆ กันเป็น multiuser ทำให้การใช้ Table พักยุ่งยากยิ่งขึ้นเนื่องจากต้องคอยตรวจสอบข้อมูลใน Table พักเพื่อให้แน่ใจว่าเป็นข้อมูลของผู้ใช้ในแต่ละ session แยกจากกันและข้อมูลไม่ตีกัน

Global Temporary Table คือคำตอบสุดท้ายที่ออราเคิลตั้งแต่ 8i เป็นต้นมาได้ให้ฟีเจอร์นี้มาเพื่อใช้สำหรับเป็นที่พักข้อมูลชั่วคราว โดยที่ผู้ใช้งานในแต่ละ session จะเห็นเฉพาะข้อมูลของตัวเอง และที่สะดวกไปกว่านั้นก็คือ เมื่อผู้ใช้ออกจากระบบหรือจบ session ออราเคิลก็จะทำการลบข้อมูลพักใน session นั้น ๆ ให้โดยอัตโนมัติ โดยมีรูปแบบคำสั่งที่ใช้ในการสร้าง table ดังนี้

create global temporary table ...table_name... (column1 data_type, column2 data_type,...)

โดยคำสั่งนี้มี option ให้เลือก 2 option คือ

  • on commit delete rows ใช้ option นี้เมื่อ commit จบ transaction แล้วข้อมูลใน table จะถูกลบทิ้งทันที โดย option นี้จะถูกระบุเป็นค่า default ถ้าไม่มีการระบุ
  • on commit preserve rows ทางเลือกนี้จะยังคงเก็บข้อมูลไว้ใน table แม้ว่าจะจบ transaction ไปแล้วก็ตาม แต่ข้อมูลจะถูกลบทิ้งเมื่อจบ session

ตัวอย่างเช่น

create global temporary table gt_temp (col1 varchar2(10),col2 varchar2(20)) on commit delete rows;

ต่อไปนี้เราก็จะได้ใช้งาน table พักโดยสามารถใช้คำสั่ง insert,update,delete เพื่อจัดการกับข้อมูล และสามารถทำ index ได้เหมือนกับ table ปกติโดยที่ไม่ต้องมาคอยจัดการลบข้อมูลทิ้งอีกต่อไป

วันอังคารที่ 15 กันยายน พ.ศ. 2552

ตัวแปร Array ใน PL/SQL

ใน PL/SQL เราสามารถสร้างตัวแปร Array เพื่อใช้เก็บข้อมูลหลาย ๆ ค่าไว้ในตัวแปรชื่อเดียวกันโดยมี index หรือหมายเลขเป็นตัวกำกับชื่อตัวแปรนั้น ๆ การกำหนดตัวแปรลักษณะนี้ทำให้เราสามารถอ้างอิงค่าในตัวแปร Array ได้หลายค่าพร้อม ๆ กันโดยการอ้างชื่อตัวแปรพร้อมกับหมายเลขกำกับ เช่น Array(1), Array(2), Array(3) เป็นต้น ทำให้เราสามารถพัฒนาโปรแกรมได้ยืดหยุ่นมากขึ้น

ตัวอย่างเช่น

01 DECLARE
02 Type phone_no_array is varray(4) of varchar2(20);
03 phone_no phone_no_array;
04 BEGIN
05 phone_no := phone_no_array('024561203','023895542','024357890','026987852');
06 DBMS_OUTPUT.PUT_LINE(phone_no(1));
07 DBMS_OUTPUT.PUT_LINE(phone_no(2));
08 DBMS_OUTPUT.PUT_LINE(phone_no(3));
09 DBMS_OUTPUT.PUT_LINE(phone_no(4)):
10* END;
SQL>/
024561203
023895542
024357890
026987852

จากตัวอย่างข้างบนในบันทัดที่ 2 เป็นการกำหนดชนิดตัวแปร Array ชื่อ phone_no_array ขนาด 4 สมาชิกโดยเก็บข้อมูลเป็น varchar2 และในบันทัดที่ 3 กำหนดให้ตัวแปร phone_no มี data type เป็น phone_no_array จากนั้นในบันทัดที่ 5 จะเป็นการกำหนดค่าเริ่มต้นให้กับตัวแปร phone_no ทั้งหมด 4 ค่า และในบันทัดที่ 6-10 เป็นการแสดงผลลัพธ์ของค่าในตัวแปร phone_no ออกมาทั้ง 4 ค่า โดยอ้างอิงชื่อตัวแปรและหมายเลขกำกับตัวแปร เช่น phone_no(1), phone_no(2) เป็นต้น

ลองมาดูกันอีกซักหนึ่งตัวอย่าง

01 DECLARE
02 Type num_array is varray(100) of number;
03 num num_array := num_array();
04 BEGIN
05 num.extend(100);
06 FOR I in 1..100 LOOP
07 num(I) := I;
08 END LOOP;
09* END

ตัวอย่างนี้เป็นการกำหนดค่าเริ่มต้นให้ตัวแปร Array ที่ชื่อว่า num ซึ่งเป็น Array ว่าง ๆ ขนาด 100 สมาชิกโดยในบันทัดที่ 3 ไม่ได้มีการกำหนดค่าของสมาชิกให้กับ Array เหมือนในตัวอย่างแรก ดังนั้นหากเราต้องการใช้งานตัวแปร Array เราจะต้องทำการ extend ก่อนจึงจะใช้งานได้ ในที่นี้บันทัดที่ 5 เป็นการ extend เพื่อใช้งาน array จำนวน 100 ค่า จากนั้นบันทัดที่ 6-8 จะเป็นการวนลูปเพื่อนำเอาค่า 1 ถึง 100 ใส่ลงไปใน Array ตามลำดับ ด้วยวิธีการนี้ทำให้เราสามารถกำหนดค่าให้กับ Array แบบ dynamic ได้โดยไม่ต้องมากำหนดค่าคงที่ให้กับ Array แต่ละตัวเหมือนกับตัวอย่างแรก

วันจันทร์ที่ 14 กันยายน พ.ศ. 2552

กู้ข้อมูล Oracle ด้วย Flashback

หลายคนคงจะเคยพลาดหรือพลั้งเผลอลบข้อมูลใน database ไปโดยไม่ตั้งใจ ถ้าบังเอิญ rollback ได้ทันก็ถือว่าโชคดีไป แต่โชคไม่ได้เข้าข้างเราเสมอไป บางครั้งข้อมูลสำคัญอาจจะถูก commit ไปแล้ว หรืออาจจะเผลอลบไปด้วยคำสั่ง Drop Table ซึ่งถือเป็นคำสั่งอันตรายอย่างยิ่งสำหรับมือใหม่หัดใช้เนื่องจากข้อมูลทั้ง table จะหายวับไปภายในพริบตา ทีนี้ก็ต้องมาตั้งสติกันว่าจะทำอย่างไรกันต่อไป ถ้ามี Back up ไว้ก็พอรอดตัวไปได้แต่ก็ต้องมาดูกันว่า Back up ไว้ล่าสุดเมื่อไร จะได้ข้อมูลกับคืนมาสมบูรณ์จนถึงจุดก่อนที่จะถูกลบหรือไม่ ปัญหาเหล่านี้เคยเจอกับตัวเองมาแล้วก็พอจะเข้าใจคนหัวอกเดียวกันว่าเป็นอย่างไร

พอออราเคิลออกเวอร์ชัน 10g ก็คงจะเข้าใจความทุกข์ยากของคนชอบพลั้งเผลอ จึงได้เพิ่มฟีเจอร์ "flashback" เข้ามาเป็นตัวช่วยในการกู้คืนข้อมูล โดยสามารถเรียกดูข้อมูลที่ถูกลบไปแล้วตามช่วงเวลาได้ (Flashback Query) และยังสามารถกู้ Table ที่ถูก Drop กลับคืนมาได้อีกด้วย (Flashback Drop)

  • Flashback Query เป็นฟีเจอร์ที่ใช้สำหรับเรียกดูข้อมูลเดิมก่อนหน้าที่จะถูกลบหรือแก้ไขโดยสามารถระบุเวลาย้อนหลังได้ ตัวอย่างเช่น

select * from employees as of timestamp to_timestamp('14/09/2009 13:00:00','dd/mm/rrrr' hh24:mi:ss');

เป็นการย้อนเวลากลับไปดูข้อมูลในวันที่ 14/09/2009 เวลา 13.00 เพื่อดูว่าข้อมูล ณ เวลานั้นเป็นอย่างไร ถ้าเป็นข้อมูลที่ต้องการเราก็สามารถดึงข้อมูลเหล่านี้เพื่อ insert กลับคืนมาได้ ถึงแม้ว่าเราจะย้อนเวลาไปดูข้อมูลเก่าได้แต่ก็ไม่ได้หมายความว่าเราจะย้อนเวลาไปได้นานเท่าที่เราต้องการเนื่องจาก Flashback Query จะไปดึงข้อมูลเก่าที่ยังค้างอยู่ใน Undo Segment โดยมีพารามิเตอร์ undo_retention เป็นตัวกำหนดว่าจะให้เก็บข้อมูลเก่าไว้ใน Undo Segment นานเท่าไร ดังนั้นเราจึงไม่สามารถย้อนเวลาไปดึงข้อมูลเก่าได้เกินกว่าที่กำหนดไว้ในพารามิเตอร์นี้

  • Flashback Drop เป็นฟีเจอร์ที่ใช้สำหรับกู้ table ที่ถูกลบด้วยคำสั่ง Drop ให้กลับคืนมาได้อย่างง่ายดาย ตัวอย่างเช่น

Flashback table employees to before drop;

โดยหลักการแล้วเมื่อ Table ถูกลบด้วยคำสั่ง Drop ข้อมูลเหล่านั้นจะยังไม่ถูกลบไปจริง ๆ เพียงแต่ว่ามันจะถูกย้ายไปเก็บไว้ที่ recyclebin แทน โดยเราสามารถเรียกดูข้อมูลใน recyclebin ได้ด้วยคำสั่ง show recyclebin ใน sql*plus หรือจะเรียกดูผ่านวิว user_recyclebin ก็ได้ นั่นคือเหตุผลที่ว่าทำไมเราจึงสามารถกู้ข้อมูลกลับมาได้

วันอาทิตย์ที่ 13 กันยายน พ.ศ. 2552

สร้าง File Dialog ใน Oracle Forms โดยไม่ง้อ WebUtil

ตั้งแต่ Oracle Forms 9i เป็นต้นไปจะไม่สามารถใช้คำสั่ง get_file_name เพื่อค้นหาไฟล์ที่ฝั่ง client ขึ้นมาใช้งานได้อีกต่อไป เนื่องจากเป็นการทำงานบน Web Platform จึงไม่สามารถใช้คำสั่งแบบเดียวกับ Client/Server ได้ ออราเคิลจึงได้ออกเครื่องมือ WebUtil ขึ้นมาเพื่อแก้ปัญหานี้โดยจะต้องทำการติดตั้งและคอนฟิกที่เครื่อง Server ซึ่งใช้ Oracle Application Server เสียก่อนจึงจะใช้งานได้ หากผู้ดูแลระบบไม่ได้ติดตั้ง WebUtil ให้ใช้งาน บทความนี้จะแนะนำทางเลือกอีกทางหนึ่งโดยไม่ต้องพึ่ง WebUtil

เราคงคุ้นเคยกันแล้วใน Oracle Forms เวอร์ชั่นเก่า ๆ ที่อนุญาตให้เราไปเรียกใช้ component อื่น ๆ เพื่อช่วยเสริมความสามารถบางอย่างที่ Oracle Forms ทำไม่ได้ที่เรารู้จักกันดีก็คือ OCX แต่ใน Oracle Forms บน Web platform นั้นได้เลิกคบกับ OCX แล้วหันไปคบค้าสมาคมกับ Java ทำให้เราต้องเปลี่ยนมาใช้ Java Bean แทน หลาย ๆ คนคงเคยเห็นแถบเครื่องมือรูปเม็ดกาแฟใน Oracle Form ก็คงจะหายสงสัยแล้วว่ามันมาแทน OCX นั่นเอง ดังนั้นในบทความนี้เราจะมาสร้าง File Dialog โดยอาศัย Java Bean มาช่วยเสริมในการใช้งาน

ลำดับแรกให้ download ไฟล์ AWTFileDialog.jar แล้วนำไปติดตั้งที่ Server โดยนำไปวางไว้ที่ /forms/java จากนั้นให้แก้ไขไฟล์ /forms/server/formsweb.cfg โดยให้เพิ่ม AWTFileDialog.jar ในบันทัดคำสั่ง archive และ archive_jini ดังนี้

archive_jini=frmall_jinit.jar,AWTFileDialog.jar
archive=frmall.jar,AWTFileDialog.jar

ทีนี้เราลองมาดูโปรแกรมตัวอย่างกัน โดยในแถบเครื่องมือให้ลากเอาเครื่องมือรูปเม็ดกาแฟ (Bean Area) มาวางไว้ใน form ของเรา จากนั้นในทริกเกอร์ When-new-form-instance จะทำการรีจิสเตอร์ java bean หลังจากนั้นให้สร้าง button และ text item โดยในปุ่มจะมีโค้ดเพื่อ invoke ให้ java bean ทำงานแล้วส่งค่าชื่อไฟล์กลับมาที่ text item ที่ต้องการ ก็จะได้ File Dialog มาใช้งานโดยไม่ต้องง้อ WebUtil อีกต่อไป

วันอังคารที่ 1 กันยายน พ.ศ. 2552

อนาคตของ Oracle Forms และ Reports


ก่อนหน้านี้มีข่าวลือกันหนาหูว่า บริษัทออราเคิลจะเลิกสนับสนุน Oracle Forms แม้แต่เพื่อนซึ่งเป็นพนักงานที่ออราเคิลเองก็ยังบอกว่าออราเคิลยังไม่มีแผนอะไรเกี่ยวกับ Oracle Forms เลย ซึ่งก็สอดคล้องกับความจริงที่ว่า หลายปีมานี้ตั้งแต่ปี 2005 เป็นต้นมาออราเคิลไม่ได้มีการปรับปรุงอะไรใหม่ ๆ เกี่ยวกับผลิตภัณฑ์ Oracle Forms หลังจากเวอร์ชั่น 10g ออกมาเลย ทำให้อดคิดไม่ได้ว่าออราเคิลคงจะเลิกสนับสนุน Oracle Forms เข้าแล้วจริง ๆ ข่าวใหญ่ที่ทำให้วงการไอทีสั่นสะเทือนเมื่อเร็ว ๆ นี้คือข่าวที่ออราเคิลเข้าไปซื้อบริษัทซันไมโครซิสเต็มส์ทำให้เชื่อได้ว่าออราเคิลคงจะจับเอา Java ซึ่งถือกำเนิดโดยซันไมโครซิสเต็มส์มาเป็นเครื่องมือสำหรับนักพัฒนาแทน Oracle Forms 10g โดยเอาผลิตภัณฑ์ JDeveloper มาเป็นตัวชูโรง ถึงกระนั้นก็ตามในใจก็ยังนึกอย่างมีความหวังว่าออราเคิลคงไม่ทอดทิ้งลูกค้าที่ใช้ Oracle Forms มามากกว่า 10 ปีซึ่งมีอยู่เป็นจำนวนมากเป็นแน่แท้ โดยเฉพาะแอพพลิเคชั่นของออราเคิลเองอย่าง E-Business Suite ก็ถูกพัฒนาด้วย Oracle Forms เช่นกัน การจะปรับเปลี่ยนเครื่องมือที่ใช้พัฒนาแอพพลิเคชั่นแล้วพัฒนาขึ้นมาใหม่คงไม่ง่ายเหมือนปอกกล้วยเข้าปากเป็นแน่

จนกระทั่งในราว ๆ เดือนกรกฎาคม 2009 นี้เองออราเคิลได้ออกผลิตภัณฑ์ Oracle Forms และ Reports ที่ปรับปรุงใหม่ในเวอร์ชั่น 11g โดยบันเดิลเป็นส่วนหนึ่งของผลิตภัณฑ์ Oracle Fusion Middleware และได้ออกมาประกาศว่าออราเคิลยังคงสนับสนุน Oracle Forms และ Reports ต่อไปอีกในอนาคต งานนี้ผู้ใช้ Fomrs & Report ได้เฮเพราะไม่ต้องมาพะวงกับการต้อง migrate ไปใช้เครื่องมืออื่น ๆ ในอนาคต นอกจากนี้ออราเคิลยังได้แนะนำให้ลูกค้าที่ยังใช้อยู่บนแพลตฟอร์ม Client-Server อัดเกรดมาใช้ Oracle Forms รุ่นล่าสุดเพื่อรองรับการทำงานในรูปแบบ Internet แอพพลิเคชั่น และรองรับกับเทคโนโลยีใหม่ ๆ อย่าง SOA (Service-Oriented Architecture) อีกด้วย