วันอังคารที่ 28 มิถุนายน พ.ศ. 2554

การพัฒนาระบบคลังข้อมูล (Building a Data Warehouse)

บทคัดย่อ ดาต้าแวร์เฮ้าส์ หรือคลังข้อมูล คือฐานข้อมูลขนาดใหญ่ที่รวบรวมข้อมูลทั้งจากแหล่งข้อมูลภายในและภายนอกองค์กร โดยมีรูปแบบและวัตถุประสงค์ ของการจัดเก็บข้อมูลแตกต่างจากฐานข้อมูลปฏิบัตการทั่วไป การพัฒนาระบบคลังข้อมูลเริ่มจากการออกแบบฐานข้อมูล ซึ่งวิธีการหนึ่งเรียกว่า ระเบียบวิธี 9 ชั้นของ Kimball จะเน้นที่การออกแบบจากระบบงานย่อยหรือดาต้ามาร์ทของแต่ละระบบงานในองค์กรก่อนจึงนำส่วนย่อยๆ นั้นมารวมเป็นระบบคลังข้อมูลขององค์กรต่อไป ทั้งนี้กระบวนการหนึ่งที่สำคัญมากในการพัฒนาระบบคลังข้อมูล คือการนำข้อมูลจากแหล่งข้อมูลเข้าสู่ดาต้ามาร์ทของแต่ละระบบ หรือเรียกว่าการแปลงข้อมูล โดยจะต้องกำหนดการส่งข้อมูล รวบรวมหรือสร้างข้อมูลภายนอก วางแผนและสร้างรูทีนการแปลงข้อมูล จึงตรวจสอบความถูกต้องของข้อมูลที่ได้ก่อนนำเข้าสู่คลังข้อมูลเพื่อให้เป็นข้อมูลที่เหมาะสมที่จะนำไปวิเคราะห์ต่อไป


1. บทนำ เนื่องจากสภาพเศรษฐกิจปัจจุบันที่ยังไม่จัดว่าพ้นภาระวิกฤตธุรกิจหลายประเภท จึงยังต้องการ การวิเคราะห์ วางแผน และตัดสินใจอย่างถูกต้อง รวดเร็วเพื่อช่วยให้ธุรกิจสามารถดำเนินไปได้ ดังนั้นข้อมูลจึงเป็นปัจจัยสำคัญยิ่งยวดต่อการดำเนินการนั้น การใช้ข้อมูลเป็นเครื่องมือสำคัญในการตัดสินใจการลงทุนทางธุรกิจและวางแผนกลยุทธ์ทางการตลาดเพื่อแข่งขันกับคู่แข่งทางการค้า ฉะนั้นก็อาจกล่าวได้ว่าการมีข้อมูลมากทำให้มีโอกาสและมีชัยเหนือคู่แข่งในระดับหนึ่ง แต่ทว่าหากมองในทางกลับกัน การมีข้อมูลจำนวนมากแต่ขาดการจัดเรียงให้เป็นระบบยุ่งยากในการเข้าถึงและค้นคืน ธุรกิจอาจต้องเสียค่าใช้จ่ายจำนวนมหาศาลในการเก็บรักษาข้อมูลเหล่านั้นไว้โดยไม่จำเป็น เพราะไม่ได้รับประโยชน์จากข้อมูลที่มี นอกจากนี้หากมีการนำข้อมูลมาวิเคราะห์อย่างผิดพลาดอาจจะก่อให้เกิดผลเสียหายได้ ซึ่งเป็นการสูญเสียโอกาสทางธุรกิจไป เพราะฉะนั้นในยุคที่ผู้บริหารมีความต้องการใช้ข้อมูล เพื่อการตัดสินใจมากขึ้น การจัดระบบระเบียบข้อมูล เพื่อนำเสนอข้อมูลที่มีคุณค่าและผ่านการกลั่นกรองแล้วแก่ผู้บริหารเพื่อใช้ในการตัดสินใจให้ทันต่อเหตุการณ์จึงเป็นสิ่งที่จำเป็นอย่างยิ่ง
แนวความคิดของการสร้างคลังข้อมูลจึงเกิดขึ้นเพื่อเป็นที่เก็บรวบรวมข้อมูลสำคัญและจำเป็นจากแหล่งต่างๆ ซึ่งเป็นประโยชน์ต่อการตัดสินใจของผู้บริหาร เพื่อให้ผู้บริหารสามารถเรียกใช้ข้อมูลที่ต้องการได้อย่างรวดเร็วและมีประสิทธิภาพมากขึ้น ข้อมูลเชิงบริหารนี้จะสามารถช่วยลดปัญหาที่เกิดจากการใช้ข้อมูลจากฐานปฏิบัติการ (operational database) ซึ่งเป็นการเก็บข้อมูลในรูปแบบ transaction system ได้ ซึ่งโดยทั่วไปปัญหาที่พบเมื่อต้องการข้อมูลที่ช่วยในการตัดสินใจได้แก่
- การเรียงข้อมูลจากฐานข้อมูลปฏิบัติการ ซึ่งมีขนาดใหญ่ ทำให้ประสิทธิภาพของระบบลดลงและทำงานได้ช้าลง
- ข้อมูลที่นำเสนอมีรูปแบบเดียว ไม่สามารถเปลี่ยนแปลงได้ตามความต้องการของผู้บริหาร
- ไม่สามารถหาคำตอบในเชิงพยากรณ์ได้
- ไม่ตอบสนองการทำคิวรี่ที่ซับซ้อนได้ดีเท่าที่ควร
- ข้อมูลถูกจัดเก็บอยู่ตามฐานข้อมูลของระบบงานต่างๆ ซึ่งยากแก่การเรียกใช้และขาดความสัมพันธ์ทางธุรกิจ


2. สิ่งที่ควรพิจารณา ก่อนสร้างคลังข้อมูลเนื่องจากการลงทุนสร้างคลังข้อมูลขึ้นมาใช้เพื่อสนับสนุนการทำงานขององค์กรนั้นจำเป็นต้องมีค่าใช้จ่ายในการลงทุนมหาศาล ทั้งที่สามารถวัดออกมาเป็นตัวเงินได้ เช่นค่าใช้จ่ายด้านฮาร์ดแวร์ ซอฟต์แวร์ และ infrastructure อื่นๆ ที่จำเป็นต้องใช้ ส่วนค่าใช้จ่ายที่ไม่เป็นตัวเงิน แต่มีความสำคัญอย่างมากได้แก่ กำลังแรงงานที่เสียไปของทรัพยากรบุคคลขององค์กรและเวลาที่ใช้ในการพัฒนา ดังนั้น เมื่อองค์กรตัดสินใจสร้างคลังข้อมูลขึ้นแล้ว ควรจะประสบความสำเร็จด้วย ทั้งนี้ Poe ได้เสนอ The Big Eight หรือ 8 ประการที่ควรให้ความสนใจ โดยมีรายละเอียดดังนี้


ควรมีเป้าหมายที่ชัดเจนร่วมของการสร้างระบบนี้ของคนในองค์กร เหมือนการตอบคำถามว่าทำไมคุณถึงคิดจะสร้างคลังข้อมูล? ซึ่งคำตอบขององค์กร ที่จะได้คือเป้าหมายที่ต้องการ โดยควรจะเขียนเป้าหมายนี้ออกมาเป็นลายลักษณ์อักษรที่ชัดเจน เพื่อให้ทีมพัฒนาได้เข้าใจเป้าหมายร่วมกัน


ทำความเข้าใจสถาปัตยกรรมของระบบ เพื่อให้ทีมพัฒนาเข้าใจตรงกัน ในที่นี้หมายถึง blueprint ที่แสดง E-R model รวมของระบบความเข้าใจที่ตรงกันทำให้งานเดินไปได้เร็วขึ้น


เทคโนโลยี่ที่ใช้ควรอยู่ในวิสัยที่เหมาะสม ทั้งด้านของตัวเงินและความยากง่ายในการเรียนรู้ ทั้งนี้หมายรวมทั้งฮาร์ดแวร์ ซอฟต์แวร์ และเครือข่าย อาจต้องมีการทดสอบและฝึกอบรมก่อนการใช้งานจริง


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


ต้องมั่นใจได้ว่าทีมพัฒนาเข้าใจเป็นอย่างดีถึงความแตกต่างกันระหว่างฐานข้อมูลปฏิบัติการและฐานข้อมูลสนับสนุนการตัดสินใจ


จัดให้มีการฝึกอบรม โดยควรเป็นการฝึกอบรมก่อนเริ่มโครงการ โดยเฉพาะอย่างยิ่งการฝึกอบรมเกี่ยวกับเครื่องมือที่องค์กรจะใช้พัฒนา ทั้งนี้อาจเป็นการฝึกอบรมจากบริษัทผู้ขาย


ควรหาบุคลากรที่มีประสบการณ์ในการพัฒนาคลังข้อมูลเพื่อทำหน้าที่เป็นผู้จัดการโครงการหรือถ้าในองค์กรไม่เคยมีประสบการณ์เลย อาจจ้างที่ปรึกษาที่มีความเชี่ยวชาญและมีประสบการณ์ด้านนี้โดยเฉพาะมาช่วยทีมพัฒนา


โปรแกรมที่จะใช้นำเสนอข้อมูลในคลังข้อมูล ต้องสามารถเรียนรู้ได้ง่ายและผู้ใช้สามารถใช้งานได้อย่างมีประสิทธิภาพ


3.แนวคิดเกี่ยวกับคลังข้อมูล

3.1 นิยามของคลังข้อมูลคลังข้อมูล หมายถึง ฐานข้อมูลขนาดใหญ่ขององค์กรหรือหน่วยงานหนึ่งๆ ซึ่ง
เก็บรวบรวมข้อมูลจากฐานข้อมูลระบบงานประจำวัน หรือเรียกอีกอย่างว่า operational database และฐานข้อมูลอื่นภายนอกองค์กร หรือเรียกว่า external database โดยข้อมูลที่ถูกจัดเก็บในคลังข้อมูลนั้น มีวัตถุประสงค์ในการนำมาใช้งานและมีลักษณะของการจัดเก็บแตกต่างไปจากข้อมูลในฐานข้อมูลระบบงานอื่น โดยข้อมูลในคลังข้อมูลจะถูกนำมาใช้เพื่อสนับสนุนการตัดสินใจบริหารงานของผู้บริหาร โดยเฉพาะการเป็นข้อมูลพื้นฐานให้กับระบบงาน เพื่อการบริหารงานอื่น เช่น ระบบ DSS และระบบ CRM เป็นต้น
3.2 คุณลักษณะเฉพาะของคลังข้อมูลจากนิยามของคลังข้อมูลที่บอกถึงความแตกต่างกันระหว่างคลังข้อมูลกับฐานข้อมูลปฏิบัติการ ซึ่งสามารถสรุปคุณลักษณะของคลังข้อมูลได้ดังนี้
1. Subject oriented หรือการแบ่งโครงสร้างตามเนื้อหา หมายถึง คลังข้อมูลถูกออกแบบมาเพื่อมุ่งเน้นไปในแต่ละเนื้อหาที่สนใจ ไม่ได้เน้นไปที่การทำงานหรือกระบวนการแต่ละอย่างโดยเฉพาะเหมือนอย่างฐานข้อมูลปฏิบัติการในส่วนของรายละเอียดข้อมูลที่จัดเก็บในระบบทั้งสองแบบก็จะแตกต่างกันไปตามความต้องการใช้งานด้วยเช่นกัน คลังข้อมูลจะไม่จำกัดเก็บข้อมูลที่ไม่มีส่วนเกี่ยวข้องกับการประมวลผลเพื่อสนับสนุนการตัดสินใจ ในขณะที่ข้อมูลนั้นจะถูกเก็บไว้ในฐานข้อมูลปฏิบัติการหากมีส่วนที่เกี่ยวข้องกับกระบวนการทำงาน
2. Integration หรือการรวมเป็นหนึ่ง ซึ่งถือได้ว่าเป็นคุณลักษณะที่สำคัญที่สุดของคลังข้อมูล คือการรวบรวมข้อมูลจากหลายฐานข้อมูลปฏิบัติการเข้าด้วยกัน และทำให้ข้อมูลมีมาตราฐานเดียวกัน เช่นกำหนดให้มีค่าตัวแปรของข้อมูลในเนื่อหาเดียวกันให้เป็นแบบเดียวกันทั้งหมด
3. Time variancy หรือความสัมพันธ์กับเวลา หมายถึงข้อมูลในคลังข้อมูล จะต้องจัดเก็บโดยกำหนดช่วงเวลาเอาไว้ โดยจะสัมพันธ์กับการดำเนินธุรกิจของหน่วยธุรกิจนั้น เพราะในการตัดสินด้านการบริหารจำเป็นต้องมีข้อมูลเปรียบเทียบในแต่ละช่วงเวลา แต่ละจุดของข้อมูลจะเกี่ยวข้องกับจุดของเวลาและข้อมูลแต่ละจุดสามารถเปรียบเทียบกันได้ตามแกนของเวลา
4. Nonvolatile หรือความเสถียรของข้อมูล หมายถึงข้อมูลในคลังข้อมูลจะไม่เปลี่ยนแปลงบ่อย ไม่ว่าจะเป็นการเพิ่มเติมข้อมูลใหม่ หรือการปรับปรุงแก้ไขข้อมูลเดิมที่บรรจุอยู่แล้ว ผู้ใช้ทำได้เพียงการเข้าถึงข้อมูลเท่านั้น


4. สถาปัตยกรรมคลังข้อมูล (Data Wharehouse Architrcture- DWA)DWA เป็นโครงสร้างมาตราฐานที่ใช้บ่อย เพื่อให้เข้าใจแนวคิด และกระบวนการของคลังข้อมูลนั้นๆ ซึ่งโดยทั่วไปแล้วคลังข้อมูลแต่ละระบบอาจจะมีรูปแบบที่ไม่เหมือนกันได้ เพื่อให้เหมาะสมกับองค์กรนั้นๆ ทั้งนี้ส่วนประกอบต่างๆ ภายใน DWA ที่สำคัญได้แก่
1. Operational database หรือ external database layer ทำหน้าที่จัดการกับข้อมูลในระบบงานปฏิบัติการหรือแหล่งข้อมูลภายนอกองค์กร
2. Information access layer เป็นส่วนที่ผู้ใช้ปลายทางติดต่อผ่านโดยตรง ประกอบด้วยฮาร์ดแวร์และซอฟต์แวร์ ที่ใช้ในการแสดงผลเพื่อวิเคราะห์ โดยมีเครื่องมือช่วย เป็นตัวกลางที่ผู้ใช้ใช้ติดต่อกับคลังข้อมูล โดยในปัจจุบันเครื่องมือที่ได้รับความนิยมเพิ่มขึ้นอย่างรวดเร็วนั้นคือ Online Analytical Processing Tool หรือ OLAP tool ซึ่งเป็นเครื่องมือที่มีความสามารถในการวิเคราะห์ที่ซับซ้อน และแสดงข้อมูลในรูปแบบหลายมิติ
3. Data access layer เป็นส่วนต่อประสานระหว่าง Information access layer กับ operational layer
4. Data directory (metadata) layer เพื่อให้เข้าใจถึงข้อมูลได้ง่ายขึ้น และเป็นการเพิ่มความเร็วในการเรียกและดึงข้อมูลของคลังข้อมูล
5. Process management layer ทำหน้าที่จัดการกระบวนการทำงานทั้งหมด
6. Application messaging layer เป็นมิดเดิลแวร์ ทำหน้าที่ในการส่งข้อมูลภายในองค์กรผ่านทางเคลือข่าย
7. Data warehouse (physical) layer เป็นแหล่งเก็บข้อมูลของทั้ง information data และ external data ในรูปแบบที่ง่ายแก่การเข้าถึงและยืดหยุ่นได้
8. Data staging layer เป็นกระบวนการการแก้ไข และดึงข้อมูลจาก external database


5. เทคนิคในการสร้างคลังข้อมูล

5.1 การเคลื่อนที่ของข้อมูลในคลังข้อมูลข้อมูลที่จัดเก็บภายในคลังข้อมูลมีการเคลื่อนที่ของข้อมูล (information flow) 5 ประเภท ดังนี้
1. Inflow คือการนำข้อมูลจากฐานข้อมูลอื่นเข้าสู่คลังข้อมูลทั้งฐานข้อมูลภายในและภายนอกองค์กร โดยในขั้นนี้อาจมีการเปลี่ยนแปลงโรงสร้างข้อมูล การทำ denormalize การลบหรือการเพิ่มฟิลด์เพื่อให้ข้อมูลทั้งหมดอยู่ในเนื้อหาที่สนใจเดียวกัน ในขั้นตอนนี้อาจใช้เครื่องมือที่เรียกว่า data warehouse tool
2. Upflow เมื่อข้อมูลที่เราต้องการอยู่ในคลังข้อมูลแล้ว ในบางครั้งอาจต้องมีการเพิ่มคุณค่าให้กับข้อมูลด้วยเพื่อให้ข้อมูลอยู่ในรูปแบบที่เป็นประโยชน์มากที่สุดต่อการนำเครื่องมือมาใช้ ซึ่งได้แก่การจัดกลุ่มข้อมูลหาค่าทางสถิติที่ซับซ้อน จัดข้อมูลให้อยู่ในรูปแบบหรือเทมเพลตมาตราฐาน
3. Downflow เป็นขั้นตอนของการปรับปรุงเปลี่ยนแปลงข้อมูลเก่า และไม่อยู่ในเนื่อหาที่องค์กรสนใจออกไปจากคลังข้อมูลขององค์กร
4. Outflow เป็นขั้นตอนที่ผู้ใช้เรียกใช้ข้อมูลในคลังข้อมูลผ่านเครื่องมือต่างๆ โดยการเรียกใช้อาจมีเพียงขอเรียกเป็นครั้งคราวเป็นประจำทุกวัน/เดือน หรือแม้กระทั่งต้องการแบบทันที
5. Metaflow ข้อมูลที่จัดเก็บในคลังข้อมูลจะถูกทำข้อมูลไว้อีกชุดหนึ่ง เป็นแหล่งที่มาของข้อมูลนั้น หรือแม้กระทั่งที่อยู่ของข้อมูลนั้นในคลังข้อมูลและข้อมูลอื่นที่เกี่ยวข้อง

5.2 วิธีการออกแบบฐานข้อมูลสำหรับคลังข้อมูลวิธีการนี้ถูกเสนอโดย Kimball ในปี 1996 เรียกว่าระเบียบวิธี 9 ชั้น หรือ Nine-Step Methodology โดยวิธีการนี้เริ่มจากการออกแบบจากส่วนย่อยที่แสดงถึงแต่ละระบบงานขององค์กร หรือเรียกอีกอย่างหนึ่งว่าดาต้ามาร์ท (data mart) โดยเมื่อออกแบบแต่ละส่วนสำเร็จแล้ว จึงนำมารวมกันเป็นคลังข้อมูล ขององค์กรในขั้นสุดท้าย ซึ่งขั้นตอนทั้ง 9 ขั้นตอน มีรายละเอียดดังนี้
1. กำหนดดาต้ามาร์ท คือการเลือกว่าจะสร้างดาต้ามาร์ทของระบบงานใดบ้าง และระบบงานใดเป็นระบบงานแรกโดยองค์กรจะต้องสร้าง E-R model ที่รวมระบบงานทุกระบบขององค์กรไว้ แสดงการเชื่อมโยงของแต่ละระบบงานอย่างชัดเจน และสิ่งที่ต้องคำนึงถึงในการเลือกระบบงานที่จะเป็นดาต้ามาร์ทแรกนั้น มี 3 ปัจจัยที่เกี่ยวข้อง ได้แก่ จะต้องสามารถพัฒนาออกมาได้ทันตามเวลาที่ต้องการ โดยอยู่ในงบประมาณที่กำหนดไว้และต้องตอบปัญหาทางธุรกิจให้แก่องค์กรได้ ดังนั้นดาต้ามาร์ทแรกควรจะเป็นของระบบงานที่นำรายได้เข้ามาสู่องค์กรได้ เช่น ระบบงานขาย เป็นต้น
2. กำหนด fact table ของดาต้ามาร์ท คือกำหนดเนื่อหาหลักที่ควรจะเป็นของดาต้ามาร์ท โดยการเลือกเอนทิตีหลักและกระบวนการที่เกี่ยวกับเอนทริตีนั้นๆ ออกมาจาก E-R model ขององค์กร นั้นหมายถึงว่าจะทำให้เราทราบถึง dimension table ที่ควรจะมีด้วย
3. กำหนดแอตทริบิวต์ที่จำเป็นในแต่ละ dimension table คือการกำหนดแอตทริบิวต์ที่บอกหรืออธิบายรายละเอียดของ dimension ได้ ทั้งนี้แอตทริบิวต์ที่เป็น primary key ควรเป็นค่าที่คำนวณได้ กรณีที่มีดาต้ามาร์ทมากกว่าหนึ่งดาต้ามาร์ทมี dimension เหมือนกัน นั่นหมายถึงว่า แอตทริบิวตืใน dimension นั้นจะต้องเหมือนกันทุกประการ นั้นไม่อาจจะแก้ไขปัญหาการจัดเก็บข้อมูลซ้ำซ้อน อันนำมาสู่ความแตกต่างกันของข้อมูลชุดเดียวกัน ปัญหานี้จึงเป็นการดีที่จะมีการใช้ dimension table ร่วมกันในแต่ละ fact table ที่จำเป็นต้องมี dimension ดังกล่าว โดยเรียก dimension table ลักษณะแบบนี้ว่า comformed และเรียก fact table ว่า fact constellation เราสามารถกำหนดข้อดีของการใช้ dimension table ร่วมกันได้ดังนี้
(1) แน่ใจได้ว่าในแต่ละรายงานจะออกมาสอดคล้องกัน
(2) สามารถสร้างดาต้ามาร์ทในเวลาต่างๆ กันได้
(3) สามารถเข้าถึงดาต้ามาร์ทโดยผู้พัฒนากลุ่มอื่นๆ
(4) สามารถรวบรวมดาต้ามาร์ทหลายๆ อันเข้าด้วยกัน
(5) สามารถออกแบบคลังข้อมูลร่วมกันได้
4. กำหนดแอตทริบิวต์ที่จำเป็นใน fact table โดยแอตทริบิวต์หลักใน fact table จะมาจาก primary key ในแต่ละ dimension table นอกจากนี้แล้ว ยังสามารถมีแอตทริบิวต์ที่จำเป็นอื่นๆ ประกอบอยู่ด้วย เช่น แอตทริบิวต์ที่ได้จากการคำนวณค่าเบื่องต้นที่จำเป็นสำหรับการคงอยู่ของแอตทริบิวต์อื่นใน fact table เรียกอีกอย่างหนึ่งว่า measure การกำหนดแอตทริบิวต์นี้ไม่ควรจะเลือกแอตทริบิวต์ที่คำนวณไม่ได้ เช่นเป็นตัวหนังสือหรือไม่ใช่ตัวเลข เป็นต้น และไม่ควรเลือกแอตทริบิวต์ที่ไม่เกี่ยวข้องกับเนื่อหาของ fact table ที่เราสนใจด้วย
5. จัดเก็บค่าการคำนวณเบื้องต้นใน fact table คือการจัดเก็บที่ได้จากการคำนวณให้เป็นแอตทริบิวต์ใน fact table ถึงแม้ว่าจะสามารถหาค่าได้จากแอตทริบิวต์อื่นๆ ก็ตาม ทั้งนี้เพื่อให้การสอบถามมีประสิทธิภาพมากขึ้น สามารถทำงานด้วยความเร็วที่เพิ่มขึ้น เนื่องจากไม่ต้องคำนวณค่าใหม่ทั้งหมด ถึงแม้ว่าจะเกิดความซ้ำซ้อนของข้อมูลในการจัดเก็บบ้างก็ตาม
6. เขียนคำอธิบาย dimension table ทั้งนี้ก็เพื่อให้ผู้ใช้สามารถใช้งานดาต้ามาร์ทได้อย่างมีประสิทธิภาพเพราะเกิดความเข้าใจอย่างดีในส่วนต่างๆ
7. กำหนดระยะเวลาในการจัดเก็บข้อมูลในฐานข้อมูล โดยอาจจะเป็นการจัดเก็บเพียงช่วงระยะเวลา 1-2 ปี หรือนานกว่านั้น ขึ้นอยู่กับความต้องการขององค์กร เนื่องจากองค์กรแต่ละประเภทมีความต้องการในการจัดเก็บข้อมูลต่างช่วงเวลากัน ทั้งนี้ขึ้นอยู่กับความจำเป็นหรือข้อกำหนดในการดำเนินธุรกิจมีข้อสังเกตอยู่ 2 ประการที่น่าสนใจและสำคัญสำหรับการออกแบบแอตทริบิวต์ในเรื่องของการจัดเก็บข้อมูล ดังนี้
(1) ข้อมูลที่ถูกจัดเก็บไว้นานเกินไปมักเกิดปัญหาการอ่าน หรือแปลข้อมูลนั้นๆ จากแฟ้มหรือเทปเก่า
(2) เมื่อมีการนำรูปแบบเก่าของ dimension table มาใช้อาจเกิดปัญหาการเปลี่ยนแปลงของ dimension อย่างช้าๆ ได้
8. การติดตามปัญหาการเปลี่ยนแปลงของ dimension อย่างช้าๆ คือ การเปลี่ยนเอาแอตทริบิวต์ของ dimension table เก่ามาใช้แล้วส่งผลกระทบต่อข้อมูลปัจจุบันของ dimension table โดยสามารถแบ่งประเภทของปัญหาที่เกิดได้ 3 ประเภท ดังนี้
(1) เกิดการเขียนทับข้อมูลใหม่โดยข้อมูลเก่า
(2) เกิดเรคอร์ดใหม่ๆ ขึ้นใน dimension
(3) เกิดเรคอร์ดที่มีทั้งค่าเก่าและใหม่ปนกันไป
9. กำหนดคิวรี่เป็นการออกแบบด้านกานภาพเพื่อให้ผู้ใช้เกิดความสะดวกในการใช้งานและสามารถทำงานได้อย่างมีประสิทธิภาพเมื่อดำเนินการทั้ง 9 ขั้นตอนสำหรับแต่ละดาต้ามาร์ทเสร็จแล้ว จึงจะนำทั้งหมดมารวมกันเป็นภาพของคลังข้อมูลขององค์กรต่อไป
5.3 การแปลงข้อมูลเข้าสู่ดาต้ามาร์ทเมื่อเราออกแบบฐานข้อมูลสำหรับแต่ละดาต้ามาร์ทเสร็จแล้ว ขั้นตอนต่อไปที่สำคัญยิ่งก็คือการนำข้อมูลจากแหล่งข้อมูลไปแปลงให้อยู่ในแพลตฟอร์มของฐานข้อมูลที่ได้ออกแบบไว้ นั่นก็คือการแปลงข้อมูล หรือ Extraction Transformation and Loading (ETL) นั่นเอง โดยที่คุณภาพของการแปลงข้อมูลเป็นสิ่งสำคัญมากสำหรับการสร้างคลังข้อมูล จะแตกต่างกันไปตามคลังข้อมูลที่แต่ละองค์กรต้องการ โดยที่การแปลงข้อมูลหมายรวมตั้งแต่การวิเคราะห์แหล่งข้อมูล กำหนดการส่งข้อมูลรวบรวมหรือสร้างข้อมูลภายนอก วางแผนและสร้างรูทีนของการแปลงข้อมูล และตรวจสอบความถูกต้องของข้อมูลที่ได้สามารถสรุปเป็นขั้นตอนได้ดังนี้
1. วิเคราะห์แหล่งข้อมูล เช่น ปริมาณของข้อมูล จำนวนและชนิดของการเข้าถึงแหล่งข้อมูล แพลตฟอร์มและภาษาโปรแกรมที่ใช้ เป็นต้น
2. ย้ายข้อมูลที่ต้องการจากระบบเดิมมาไว้ในบริเวณที่ใช้ปรับแต่งข้อมูล หรือเรียกบริเวณนี้ว่า staging area เพื่อนำมาเลือกเฉพาะส่วนที่ต้องการแปลงข้อมูลและตรวจสอบความถูกต้อง หรือการทำความสะอาดข้อมูล
3. กำหนด primary key ของ fact table และ dimension table และกำหนด foreign key ระหว่าง fact table กับ dimension table
4. ย้ายข้อมูลที่ทำความสะอาดแล้วจาก staging area ลงสู่เซิร์ฟเวอร์ของดาต้ามาร์ท
5. สร้าง metadata ของแต่ละดาต้ามาร์ท โดยเก็บรายละเอียดของข้อมูลการอัปเดตและส่งออกไปไว้ในดาต้ามาร์ท
6. ตรวจสอบความถูกต้องของข้อมูล ซึ่งจะต้องกระทำตลอดทั้งกระบวนการแปลงข้อมูลจำทำได้ดังนี้
(1) ตรวจสอบผลรวมทั้งหมดของจำนวนข้อมูลที่ดึงมาจากแหล่งข้อมูลที่เพิ่มเข้าไป
(2) ตรวจแก้ข้อมูลในระบบเดิมของแหล่งข้อมูล หรือในรูทีนของการแปลง ซึ่งควรจะเก็บข้อมูลในการตรวจแก้ไว้ใน metadata ของการแปลงข้อมูลด้วย
(3) ตรวจสอบค่าของข้อมูลให้ถูกต้องในกระบวนการรวบรวมข้อมูล
(4) ตรวจสอบผลรวมของข้อมูลหลังจากย้ายข้อมูลลงสู่ดาต้ามาร์ทแล้ว


6. สรุป คลังข้อมูลเป็นการรวบรวมข้อมูลจากฐานข้อมูลของระบบงานปฏิบัติงานประจำวันขององค์กร แล้วนำมาแปลงข้อมูลให้อยู่ในรูปแบบ ที่เหมาะสมในการเก็บและสะดวกในการใช้งาน แล้วจึงนำข้อมูลนั้นเข้าไปเก็บในคลังข้อมูล  การพัฒนาหรือสร้างคลังข้อมูลจากฐานข้อมูลจะต้องมีการพิจารณาถึงองคืประกอบที่จำเป็นในการสร้างให้เหมาะสมด้วย ทั้งนี้เพื่อให้เกิดความคุ้มค่าในการลงทุนและเกิดประโยชน์สูงสุดต่อองค์กร ถึงแม้ว่าเทคโนโลยีคลังข้อมูล จะให้ประสิทธิภาพในการใช้ข้อมูลอย่างมากก็ตาม แต่สิ่งที่ต้องคำนึงด้วยคือทรัพยากรที่องค์กรจะต้องทุ่มเทลงไปในการพัฒนาที่อาจจะเกิดขึ้นจนองค์กรไม่สามารถจะพัฒนาระบบนี้จนสำเร็จ และนำมาใช้งานได้ เกิดการลงทุนที่สูญเปล่า ดังนั้นจึงต้องมีการวางแผนควบคุมและจัดการให้รอบคอบ.

วันจันทร์ที่ 27 มิถุนายน พ.ศ. 2554

ติดตั้ง MultiSite (mu) ให้กับ WordPress 3


Activate mod_rewrite module on Apache2.2 Windows installment.

I decided to take a look at highly glorified cms called snews and test it locally on my Apache2.2 server but struggled to enable mod_rewrite module in order to get my urls rewritten.
As you know mod_rewrite is used for rewriting URLs at the server level. The best example would WordPress permalinks, where you decide how url of your blog look like. By default it would be yourblog.com/?p=123 but with a help of mod_rewrite you get something like this:yourblog.com/post-about-this

How to check if mod_rewrite works on your Apache server?

I noticed that opening phpinfo page (create file phpinfo.php with this source code:
<?php phpinfo(); ?>
and load via localhost) isn’t enough to determine whether mod_rewrite module works. You should test this by practicaly trying to change url.
  • At first create .htaccess file with the code:
    RewriteEngine on
    RewriteRule ^first.html$ second.html
  • Create 2 html files named first.html and second.html and write 1 or 2, or first and second in them so that you could easily distinguish that in first.html a word “first” is written. Put those 2 files in the same folder where you put .htaccess file.
  • Load first.html via localhost. Your mod_rewrite works if you see first.html in the address bar but word “second” displayed in the page. Otherwise you need to enable mod_rewrite module.

Enable mod_rewrite module

  • Open httpd.conf file (locate it in start->apache program menu or go to apache installation directory and conf folder) and search (use ctrl+f) for #LoadModule rewrite_module string. Uncomment this line, i.e.
    line #LoadModule rewrite_module modules/mod_rewrite.so
    becomes LoadModule rewrite_module modules/mod_rewrite.so

  • Find and uncomment Options Indexes FollowSymLinks line
  • Change AllowOverride None to AllowOverride All

  • Restart Apache server and check again if mod_rewrite works
    ------------------------------------------------------------------------------------------------------------------------------------------------


    การตั้งค่า Multisite สำหรับ wordpress

    พฤษภาคม 18th, 2011 by kazama
    สำหรับเวิร์ดเพรสรุ่นตั้งแต่ 3.0 ขึ้นไป wordpress mu ได้รวมเข้ากับ wordpress ทำให้ wordpress ตัวปกติมีความสามารถเหมือนกับ wordpress mu
    วิธีการตั้งค่า multisite สำหรับ wordpress
    เริ่มด้วยการตั้งค่า subdomain “*” เพิ่มเข้าไปสำหรับเว็บไซต์ที่เราต้องการทำ wordpress multisite สำหรับการติดตั้งแบบ subdomain เท่านั้น
    เวิร์ดเพรส, wordpress, multisite
    เพิ่มคำว่า
    define(‘WP_ALLOW_MULTISITE’, true);
    เข้าไปในไฟล์ wp-config.php ตามในรูป
    เวิร์ดเพรส, wordpress, multisite
    เมื่อเข้ามาใน dashboard ของ wordpress จะเห็น function “network” เพิ่มเข้ามาในเมนู tool ให้กด install ได้เลย wordpress ที่ผมใช้นี้ติดตั้งนานแล้ว มีบทความอยู่ ทำให้ไม่สามารถเลือกติดตั้งแบบ subdirectory ได้ ต้องติดตั้งแบบ subdomain
    เวิร์ดเพรส, wordpress, multisite
    เมื่อกดติดตั้งแล้ว ในหน้าจอควบคุมจะขึ้นคำแนะนำให้ทำตามอีกสามขั้นตอน
    1. สร้าง folder “blogs.dir” ภายใต้ directory “wp-content”
    2. เพิ่มข้อความเหล่านี้ลงใน wp-config.php
    define( ‘MULTISITE’, true );
    define( ‘SUBDOMAIN_INSTALL’, true );
    $base = ‘/’;
    define( ‘DOMAIN_CURRENT_SITE’, ‘feelthailand.com’ );
    define( ‘PATH_CURRENT_SITE’, ‘/’ );
    define( ‘SITE_ID_CURRENT_SITE’, 1 );
    define( ‘BLOG_ID_CURRENT_SITE’, 1 );
    เปลี่ยน “feelthailand.com” เป็นชื่อเว็บของคุณ หรือ copy ข้อความใน dashboard ไปใส่
    3. เพิ่มข้อความเหล่านี้ลงใน .htaccess
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ – [L]
    # uploaded files
    RewriteRule ^files/(.+) wp-includes/ms-files.php?file=$1 [L]
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ – [L]
    RewriteRule . index.php [L]
    เมื่อตั้งค่าเสร็จแล้ว ระบบจะให้เรา login ใหม่ เมื่อเข้าสู่ระบบเท่านี้เราก็พร้อมที่จะใช้งาน wordpress multisite แล้ว ดูจากรูปเราสามารถเข้าระบบจัดการของ network admin เพื่อสร้าง multisite ได้
    เวิร์ดเพรส, wordpress, multisite

    วันอาทิตย์ที่ 26 มิถุนายน พ.ศ. 2554

    iReport

    โดย RACHJULY


    ปกติถ้าพูดถึง Crystal Report คงไม่มีใครในวงการ Software Development ที่ไม่รู้จัก แต่คราวนี้อยากจะแนะนำให้รู้จักโปรแกรมอีกตัวหนึ่งที่มีความสามารถไม่ได้ น้อยไปกว่า Crystal Report เลย แถมยังเป็น Open Source อีกด้วย
    iReport Features

    • 100% pure java
    • Visual reporting
    • Retrive data using JDBC, TableModels, JavaBeans, XML, Hibernate, CSV
    • Create charts, images, subreport, barcode, crosstab
    • support output in PDF, RTF, XML, XLS, CSV, HTM
    Download and Install
    สามารถเข้าไป download ได้ที่ http://jasperforge.org/sf/projects/ireport

    หลังจาก Download มาแล้วก็การติดตั้งบน Windows ซึ่งไม่มีอะไรยุ่งยาก เลือก Option แล้วก็ Next จนเสร็จ


    First Lookหลังจากทำการติดตั้งเสร็จ เมื่อเปิดโปรแกรมขึ้นมาก็จะเป็นดังรูป


    Basic Concept
    iReport เป็น Tool ที่ทำงานร่วมกับ Java Library สำหรับออก Report ชื่อว่า JasperReports โดยการทำงานของ JasperReorts จะเป็นดังนี้

    1. เขียน code ของ Report ให้เป็นตามรูปแบบที่กำหนดไว้ โดย Syntax จะเป็นแบบ XML
    2. Jasper Compiler จะทำแปลง XML file ออกมาเป็น Report ที่เป็น Jasper file
    3. JRDatasource จะเป็นส่วนสำหรับรับข้อมูลที่จะแสดงใน Report
    4. JasperReporting Engine จะทำการรวม Data จาก JRDatasource และ Jasper file แล้วแสดงผลออกไปเป็น Report


    การแสดงผลของ Jasper สามารถแสดงได้หลายแบบได้แก่ HTML และ Swing หรือ Export ออกมาเป็น File แบบต่างๆได้แก่ PDF, Excel, RTF, CSV


    iReport เป็น tool ที่มาช่วยให้สามารถทำงานกับ JasperReports ได้ง่ายขึ้น โดยจะช่วยสร้าง XML ที่จะเป็น Source Code ที่จะถูก Compile เป็น Jasper file แล้วนำไปใช้ออก report ต่อไป


    เริ่มต้นสร้าง Reportเริ่มจากการสร้าง Report ง่ายๆกันก่อน

    1. ไปที่ File->New Document จะมี Dialog ขึ้นมาให้เลือก ขนาดกระดาษและ option อื่นๆ ก็เลือก A4 ตามมาตรฐาน

    2. จะเห็น Report ว่างๆขึ้นมา โดยจะแบ่งออกเป็นส่วนๆ ซึ่งถ้าใครเคยใช้ Crystal Report หรือ Tool ที่สำหรับสร้าง Report มาก่อนก็จะเข้าใจ (ถ้าไม่เข้าใจจะมีอธิบายต่อไป)

    3. เลือก Element ที่ชื่อว่า Static Text (ตามรูป)

    4. สร้าง Static Text ในส่วนของ Title จะเห็น properties ของ Text ที่ Element Properties ซึ่งเราสามารถจัด Format ได้ตามสะดวก หรือจะคลิ้กขวาแล้วเลือก Properties ก็ได้เหมือนกัน

    5. ที่ Tab Font ปรับขนาด Font เป็น 36 ,จัดให้อยู่ตรงกลาง และที่ Tab Static Text เปลี่ยนเป็นคำว่า Hello iReport

    6. เรียก Menu Build->Execute Empty Data Source ซึ่งโปรแกรมจะบังคับให้เรา Save ก่อน

    7. Report จะแสดงออกมาใน Report Viewer

    8. ถ้าต้องการให้ Report Export ออกมาในรูปแบบอื่นๆก็เลือกได้จาก Menu Build แล้วสั่ง Execute (File ที่ Export ออกมาปกติจะอยู่ใน Folder เดียวกับที่ Install iReort)


    --------------------------------------------------------------------------------------------------------------



    ใน iReport 1.2.5 สามารถสร้าง Connection เพื่อไปดึง Data ได้หลายแบบ ได้แก่
    1. Database JDBC connection
    2. XML file datasource
    3. JavaBeans set Datasource
    4. Custom JRDatasource
    5. File CSV datasource
    6. JRDataSourceProvider
    7. Hibernate connection
    8. Spring loaded Hibernate Connection
    9. EJBQL connection
    10. Mondrian OLAP connection
    ในส่วนต่อไปเป็นการสร้าง Connection ไปยัง Database JDBC connection กับ JRDataSourceProvider
    1. การสร้าง Database JDBC connection
    ไปที่ menu Data->Connections/Datasources กด New จะมี Dialog ขึ้นมาให้เลือก Connection ก็ใส่ Option ตาม Connect ที่ต้องการ ในตอนนี้จะเลือกเป็น MySQL JDBC Connection ตามรูป

    2. ใช้ Report Wizard สร้าง Report ขึ้นมาจาก Connection ที่สร้างไว้ (menu File-> Report Wizard)
    3. ในช่อง SQL Query ให้ใส่ SQL เพื่อดึงข้อมูลที่จะให้แสดงใน Report และเมื่อกด Next จะแสดง Field ทั้งหมดที่ SQL Select ขึ้นมา ให้เลือก Field ที่จะแสดงและกด Next ต่อไป4. เลือก Group และเลือก Template ที่จะใช้แล้ว ก็จะได้ Report ออกมาแบบนี้ (เลือก Tabular layout, classicT.xml) แก้ Report Title ให้เป็นตามต้องการ
    5. ไปที่ menu Build->Execute (with active connection) เพื่อเป็นการ Preview Report กับ Data


    --------------------------------------------------------------------------------------------------------------




    การสร้าง Connection ไปยัง JRDataSourceProvider
    ขึ้นตอนจะเป็นดังนี้
    1. ที่ Java project Create Entity Bean
    2. ที่ Java project Create Class extended from JRAbstractBeanDataSourceProvider
    3. ที่ iReport Save Classpath โดยไปที่ menu Option->Classpath แล้ว Add Folder ของ Project แล้ว Save
    4. สร้าง Connection โดยเลือกเป็น JRDataSourceProvider และใส่ JRAbstractBeanDataSourceProvider Extends Class
    5. สร้าง Report โดยใช้ Report Wizard ตามปกติ โดยจะเห็น Properties ของ Entity Bean เป็น Field ใน Report

    ต่อไปมาดูการสร้างอย่างละเอียด
    1. สร้าง Entity Bean ที่จะเอาไว้เก็บข้อมูลของ Employee ชื่อว่า Employee
    package data.factory;
    
    import java.io.Serializable;
    import java.util.Date;
    
    public class Employee implements Serializable {
    
    private static final long serialVersionUID = -2601582524413665788L;
    private String empNo;
    private String empName;
    private String depNo;
    private String depName;
    private Date startDate;
    
    public Employee(String empNo, String empName,
       String depNo, String depName, Date startDate) {
    super();
    this.empNo = empNo;
    this.empName = empName;
    this.depNo = depNo;
    this.depName = depName;
    this.startDate = startDate;
    }
    public String getDepNo() {return depNo;}
    public void setDepNo(String depNo) {this.depNo = depNo;}
    public String getEmpName() {return empName;}
    public void setEmpName(String empName) {this.empName = empName;}
    public String getEmpNo() {return empNo;}
    public void setEmpNo(String empNo) {this.empNo = empNo; }
    public Date getStartDate() {return startDate;}
    public void setStartDate(Date startDate) {this.startDate = startDate;}
    public String getDepName() {return depName;}
    public void setDepName(String depName) {this.depName = depName;}
    }



    2. ที่ Java project Create Class extended from
    JRAbstractBeanDataSourceProvider เพื่อที่ให้เป็นตัวที่จะ Query Data มาให้ Report


    package data.factory;
    import java.sql.*;
    import java.util.*;
    import java.util.Date;
    import data.connect.DBConnect;
    import net.sf.jasperreports.engine.*;
    import net.sf.jasperreports.engine.data.JRAbstractBeanDataSourceProvider;
    import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
    public class EmployeeReport
    extends JRAbstractBeanDataSourceProvider {
    public EmployeeReport() {
    super(Employee.class);
    }
    public void dispose(JRDataSource arg0) throws JRException {
    }
    public JRDataSource create(JasperReport arg0) throws JRException {
    ArrayList<Employee> list=new ArrayList<Employee>();
    String sSQL="SELECT EmpNo , EmpName , "
         +"StartDate , employee.DepNo,DepName"
         +" FROM employee "
         +" INNER JOIN department"
         +" ON employee.DepNo = department.depno "
         +" where employee.DepNo='S01'"
         +" order by EmpNo";
    try{
     Connection connection=DBConnect.getMySqlConnection();
     PreparedStatement prs=connection.prepareStatement(sSQL);
     ResultSet rs=prs.executeQuery();
     while(rs.next()){
       list.add(new Employee(rs.getString("EmpNo")
               ,rs.getString("EmpName")
               ,rs.getString("DepNo"),rs.getString("DepName")
               ,new Date(rs.getDate("StartDate").getTime())));
     }
    }
    catch(Exception ex){
     ex.printStackTrace();
    }
    return new JRBeanCollectionDataSource(list);
    }
    }

    3. ที่ iReport Save Classpath โดยไปที่ menu Option->Classpath แล้ว Add Folder ของ Project แล้ว Save
    4. สร้าง Connection เป็น JRDataSourceProvider แล้วใส่ชื่อ Class ที่เราสร้างไว้ ลอง Test ดูว่า Connect สำเร็จมั้ย
    5. สร้าง Report โดยใช้ Report Wizard ตามปกติ โดยจะเห็น Properties ของ Entity Bean เป็น Field ใน Report




    --------------------------------------------------------------------------------------------------------------




    การเรียก Report มาแสดงบนจากหน้า Web จะต้องมี Library ของ JasperReport อยู่ด้วยโดย File ที่ใช้คือ
    1. jasperreports-1.2.5.jar
    2. itext-1.3.1.jar
    3. commons-javaflow-20060411.jar
    โดยสามารถไป Copy ได้จาก Folder ที่ Install iReport C:\Program Files\JasperSoft\iReport-1.2.5\lib

    นี้เป็นตัวอย่าง File JSP ที่จะใช่แสดง Output ออกมาเป็น PDF file
    โดย Parameter ที่ต้องการคือ
    1. ReportName - ชื่อ File ของ Report ไม่ต้องมีนามสกุล
    2. DataSource - ใช้ในกรณีที่เป็นการ Connect โดยใช้ JRDataSourceProvider
    ตัวอย่างการเรียก Report ผ่าน JSP
    • http://localhost:8080/iReport1/ExportReport.jsp?ReportName=EmployeeList แบบใช้ JDBC Connection
    • http://localhost:8080/iReport1/ExportReport.jsp?
      ReportName=EmployeeList&DataSource=data.factory.EmployeeReport
      แบบ JRDataSourceProvider

    <%@page import="java.util.*"%>
    <%@page import="data.connect.DBConnect"%>
    <%@page import="java.sql.Connection"%>
    <%@page import="net.sf.jasperreports.engine.*"%>
    <%@page import="net.sf.jasperreports.engine.data.JRAbstractBeanDataSourceProvider"%>
    <%@page import="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"%>
    <%@page import="net.sf.jasperreports.engine.export.*"%>
    <%
    String dataSource = request.getParameter("DataSource");//DataSource
    String sReportPath = getServletContext().getRealPath("/Reports/"
       + request.getParameter("ReportName") + ".jrxml");
    //Mapping Query String to Report's Parameter
    Map<String, Object> parameters = new HashMap<String, Object>();
    Enumeration eParaName = request.getParameterNames();
    if (eParaName != null){
    while (eParaName.hasMoreElements()) {
     Object obj = eParaName.nextElement();
     parameters.put(obj.toString(), request.getParameter(obj.toString()));
    }
    }
    //Compile Report jrxml --> jasper
    JasperReport jasperReport = JasperCompileManager.compileReport(sReportPath);;
    JasperPrint jasperPrint=null;
    try {
    if (dataSource == null) { //Check Data Source Type
     //Get Data from Connection
     //Create connection to Database
     Connection connection=DBConnect.getMySqlConnection();
     jasperPrint =
       JasperFillManager.fillReport(jasperReport, parameters, connection);
    }
    else{
     //Get Data from Data Source Class
     JRAbstractBeanDataSourceProvider dsf
       = (JRAbstractBeanDataSourceProvider)Class.forName(dataSource).newInstance();
     JRBeanCollectionDataSource ds = (JRBeanCollectionDataSource)dsf.create(jasperReport);                
     if (ds != null) {
       jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, ds);
     }          
    }
    //Stream output to PDF file
    ServletOutputStream sosStream = response.getOutputStream();
    JRExporter exporter = new JRPdfExporter();//PDF Export  
    exporter.setParameter( JRExporterParameter.JASPER_PRINT, jasperPrint );
    //Set Stream header
    response.setHeader (
       "Content-Disposition", "attachment;filename=\""
       +request.getParameter("ReportName")+".pdf\"");
    exporter.setParameter( JRExporterParameter.OUTPUT_STREAM, sosStream);
    exporter.exportReport();
    sosStream.close();
    }
    catch (Exception ex1){
    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex1.getMessage());
    ex1.printStackTrace();
    return;
    }
    
    %>