ABAP - 4 ตอนรู้จักภาษา เปิดเบื้องหลังของ SAP R/3

 และแล้วก็มาถึงตอนที่สำคัญที่สุดของการเขียนโปรแกรมด้วยภาษา ABAP ก็คือเรื่องของคำสั่งที่ใช้ในการเข้าถึงข้อมูลที่ดาต้าเบสเซิร์ฟเวอร์ (Database Server) ในระบบ SAP R/3 โดยที่ในภาษา ABAP นั้น เราสามารถใช้คำสั่ง SQL ในการเข้าถึงข้อมูลที่ดาต้าเบสเซิร์ฟเวอร์ได้ 2 รูปแบบด้วยกัน คือ Open SQL และ Native SQL ซึ่งเนื้อหาที่ผมจะกล่าวถึงต่อไปนี้ จะเน้นเฉพาะ Open SQL ซึ่งเป็นมาตรฐานภาษา SQL ของ SAP เท่านั้น เพราะ Native SQL จะเป็น SQL มาตรฐานของเอ็นจิ้นแต่ละตัว ไม่ว่าจะเป็น ORACLE, Informix, DB2 หรือ MS SQL Server เป็นต้น


Open SQL

ข้อดีของการใช้ Open SQL ในการเข้าถึงข้อมูลในฐานข้อมูลของระบบ SAP R/3 คือประการแรก มันเป็นภาษามาตรฐานของระบบ SAP ดังนั้นไม่ว่าคุณจะใช้ระบบ SAP บนดาต้าเบสเซิร์ฟเวอร์ของ ORACLE, Informix, DB2 หรือแม้แต่ MS SQL Server ก็ตาม ภาษา SQL ที่คุณใช้ จะมีรูปแบบหรือซินแท็กซ์ที่เหมือนกันหมด นอกจากนี้เมื่อใดก็ตามที่มีการใช้ Open SQL ในการเข้าถึงข้อมูลที่ฐานข้อมูล ระบบจะค้นหาข้อมูลที่ Table Buffer ในหน่วยความจำของ Application Server (R/3 Instance) ก่อนเสมอ และถ้าพบข้อมูลที่ต้องการ ระบบก็จะไม่ส่งคำสั่ง SQL Request นี้ ไปที่ดาต้าเบสเซิร์ฟเวอร์ Database Server แต่อย่างใด ซึ่งช่วยเพิ่มความเร็วในการทำงานด้วย

ถ้ายังจำขั้นตอนการทำงานของโปรแกรม ABAP ในระบบ SAP R/3 กันได้ การทำงานของโปรแกรม ABAP จะเป็นลักษณะของ Interpreter ก็คือเมื่อ Taskhandler พิจารณาคำสั่งในโปรแกรม ABAP ที่มันกำลังทำงานอยู่แล้ว พบว่าเป็นคำสั่งประเภท Open SQL มันจะส่งคำสั่ง Open SQL นี้ไปให้กับ DB Interface ทำงานตามหน้าที่ของมัน คือแปลงคำสั่ง Open SQL ให้เป็น Native SQL เพื่อส่งไปยังดาต้าเบสเซิร์ฟเวอร์ต่อไป (กรณีที่ข้อมูลที่ต้องการไม่มีอยู่ใน Table Buffer) เพราะว่าดาต้าเบสเซิร์ฟเวอร์ไม่รู้จักคำสั่ง Open SQL ดังนั้น DB Interface จึงทำหน้าที่เหมือนกับล่ามในการแปลภาษา Open SQL ของ SAP ให้เป็น Native SQL ตามดาต้าเบสเอ็นจิ้นในระบบ SAP R/3



.....รูปที่ 1. ด้วยลักษณะของโปรแกรม ABAP ที่ทำงานแบบ Interpreter หลังจาก Taskhandler พิจารณาคำสั่งแล้วพบว่าเป็น Open SQL มันจะส่งต่อไปให้กับ DB Interface แปลงคำสั่ง Open SQL ให้เป็น Native SQL.....


สำหรับคำสั่ง Open SQL นั้น จะมีอยู่ด้วยกัน 4 คำสั่งหลักคือ




  • Select เป็นคำสั่งที่ใช้ในการอ่านข้อมูลของตารางที่ฐานข้อมูล







  • Insert เป็นคำสั่งที่ใช้ในการเพิ่มข้อมูลให้กับตารางที่ฐานข้อมูล







  • Delete เป็นคำสั่งที่ใช้ในการลบข้อมูลของตารางที่ฐานข้อมูล







  • Update เป็นคำสั่งที่ใช้ในการแก้ไขข้อมูลของตารางที่ฐานข้อมูล

    ซึ่งในส่วนต่อไปนี้ ผมจะกล่าวถึงเฉพาะคำสั่ง Select เท่านั้นนะครับ สำหรับซินแท็กซ์ของคำสั่ง Select จะเป็นดังนี้

    Select Which columns?
    Into Where to place the record?
    From Which table?
    Where Which lines?

    เช่น ถ้าเราต้องการอ่านข้อมูลของตาราง customers ที่ฐานข้อมูลของดาต้าเบสเซิร์ฟเวอร์ โดยที่สมมติว่าในตาราง customers มีข้อมูลดังต่อไปนี้


    Tables customers.
    Select * from customers.
    Write: / customers-id, customers-name.
    Endselect.

    โดยที่คำสั่ง select * from customers ซึ่งจะต้องปิดด้วย Endselect นั้น จะเป็นคำสั่งประเภทบล็อกที่มีการวนลูป พร้อมทั้งอ่านข้อมูลในแบบหลายเรคอร์ดหรือ Multiple Record จากตารางที่ระบุหลัง From ซึ่งในที่นี้คือ ตาราง customers นั่นเอง และเมื่อใดก็ตามที่เราต้องการอ่านข้อมูลทุกคอลัมน์ (Select * ...) และไม่มีการใช้ออปชัน Into ในคำสั่ง Select เราจะต้องสร้าง Table Structure ของตารางนั้นๆ ที่ Memory Space จากคำสั่ง Tables ก่อนเสมอ เช่น Tables customers เราก็จะได้ Structure ของตาราง customers ( เหมือนกับ Structure ที่สร้างจากคำสั่ง Data begin of... ทุกประการ) ดังรูป
    นั่นเอง โดยที่ถ้าเราไม่ระบุออปชัน Into ในคำสั่ง Select ระบบจะใส่ออปชัน Into ตามด้วย Structure ของตารางที่ระบุหลัง From ให้เรา เช่น จากคำสั่ง Select * from customers เมื่อระบบนำคำสั่งนี้ไปทำงาน มันจะแปลงให้เป็นรูปแบบของคำสั่ง Select ดังนี้คือ Select * into customers from customers แต่ถ้าเราระบุออปชัน Into ตามด้วย Structure ชื่ออื่น ที่ไม่ใช่ชื่อของตารางที่มีการอ่านข้อมูล เราก็ไม่จำเป็นที่จะต้องสร้าง Table Structure ของตารางนั้นๆ จากคำสั่ง Tables แต่อย่างใด โดยที่คำสั่ง Write ก็จะต้องระบุฟิลด์ของ Structure ที่ชื่อ wa_customers แทนด้วย เช่น

    Data wa_customers like customers.
    Select * into wa_customers from customers.
    Write: / wa_customers-id,wa_customers-name.
    Endselect. 






  • คราวนี้เรามาดูการทำงานของคำสั่ง Select ... Endselect ว่ามันจะทำงานในแบบ Set of Record เหมือนกันกับ Standard SQL หรือไม่ โดยที่หลังจากที่ระบบสร้าง Structure ของตาราง customers จากคำสั่ง Tables customers เสร็จเรียบร้อยแล้ว จากนั้นเมื่อ Taskhandler พบว่าคำสั่งต่อไปของโปรแกรม เป็นคำสั่งประเภท Open SQL ในตัวอย่างนี้ก็คือคำสั่ง Select ... Endselect ระบบก็จะส่งคำสั่งนี้ให้กับ DB Interface ทำงานตามหน้าที่ของมันก็คือแปลง Open SQL ให้เป็น Native SQL (เพราะ Database Server ไม่รู้จักคำสั่ง Select ... Endselect นั่นเอง) จากนั้น DB Interface ก็จะส่งคำสั่ง Native SQL นี้ไปให้กับดาต้าเบสเซิร์ฟเวอร์ เพื่อค้นหาข้อมูลตามเงื่อนไขของคำสั่ง Select ซึ่งในขั้นตอนนี้ ดาต้าเบสเซิร์ฟเวอร์จะทำงานตามคำสั่ง Select ในลักษณะของ Set of Record

    จากนั้นเมื่อดาต้าเบสเซิร์ฟเวอร์พบข้อมูลที่ต้องการแล้ว ก็จะส่งผลลัพธ์ที่ได้จากการทำ Query กลับไปให้กับ DB Interface ในพื้นที่ที่เรียกว่า Result Set ซึ่งเป็นพื้นที่หน่วยความจำของ DB Interface ดังรูปที่ 2



    .....รูปที่ 2. เมื่อดาต้าเบสเซิร์ฟเวอร์พบข้อมูลที่ต้องการแล้ว ก็จะส่ง Result หรือผลลัพธ์ของข้อมูลทั้งหมดที่ได้จากการทำ Query กลับไปให้กับ DB Interface ในพื้นที่ของ Result Set.....


    โดยที่จะมี Pointer หรือ Cursor ชี้อยู่ที่เรคอร์ดแรกใน Result Set เสมอ หลังจากที่ได้รับ Result กลับมาจากดาต้าเบสเซิร์ฟเวอร์ จากนั้นระบบจึงเริ่มทำงานคำสั่ง Select ... Endselect ตามขั้นตอนดังต่อไปนี้




  • เริ่มต้นทำงานคำสั่ง Select * from customers โดยหน้าที่ของคำสั่งนี้ ระบบจะอ่านข้อมูลจาก Result Set ในเรคอร์ดที่ Pointer ชี้อยู่ จากนั้นระบบจะคัดลอกหรือ Copy ข้อมูลทั้งแถวจาก Result Set มาไว้ที่ Structure ที่ระบุหลังออปชัน Into แต่ถ้าไม่ระบุ Into ระบบก็จะนำข้อมูลที่อ่านได้จาก Result Set ไปเก็บไว้ที่ Table Structure ที่ Memory Space ดังรูปที่ 3



    .....รูปที่ 3. ผลจากการทำงานตามคำสั่ง Select * from customers.....








  • จากนั้นระบบก็จะทำคำสั่งที่อยู่ภายในบล็อกของ Select ... Endselect ทั้งหมด ในที่นี้ก็คือคำสั่ง Write: / customers-id,customers-name ซึ่งก็คือระบบจะอ่านข้อมูลฟิลด์ id และ name ของ Structure ชื่อ customers ที่ Memory Space นั่นเอง ซึ่งเราจะได้ข้อมูลเรคอร์ดแรกที่หน้าจอจากคำสั่ง Write นี้







  • จากนั้นเมื่อพบคำสั่งต่อไปคือ Endselect ระบบก็จะเช็กว่าที่ Result Set มีเรคอร์ดที่ต้องอ่านถัดไปหรือไม่ ถ้ามีก็จะเลื่อน Pointer ไปยังเรคอร์ดถัดไป จากนั้นก็จะโอนการทำงานกลับไปที่คำสั่ง Select ต่อไป







  • การทำงานของโปรแกรมก็จะกลับมาที่คำสั่ง Select มันก็จะทำงานตามหน้าที่ของมันคือ อ่านข้อมูลที่ Result Set ตามที่ Pointer ชี้อยู่ จากนั้นก็คัดลอกข้อมูลของเรคอร์ดปัจจุบันใน Result Set ไปไว้ที่ Table Structure ใน Memory Space ต่อไป







  • จากนั้นระบบก็จะทำงานคำสั่งที่อยู่ภายในบล็อกของ Select ... Endselect ต่อไป ก็คือคำสั่ง Write ... เราก็จะได้ข้อมูลเรคอร์ดที่สองที่หน้าจอ







  • จากนั้นคำสั่ง Endselect จะเช็กว่ามีเรคอร์ดที่ต้องอ่านต่อไปที่ Result Set หรือไม่ ถ้ามีก็จะเลื่อน Pointer ไปยังเรคอร์ดถัดไป จากนั้นก็จะโอนการทำงานกลับไปที่คำสั่ง Select ต่อไป ซึ่งการทำงานจะเป็นเช่นนี้ตลอดไปจนกว่าจะหมดเรคอร์ดที่จะอ่านที่ Result Set







  • เมื่อหมดเรคอร์ดที่จะต้องอ่านที่ Result Set แล้ว การทำงานของโปรแกรมก็จะหลุดออกจากบล็อกของ Select ... Endselect ไปทำงานในคำสั่งที่อยู่ถัดไปจากคำสั่ง Endselect

    จะเห็นได้ว่าข้อมูลที่อยู่ใน Table Structure ที่ Memory Space นั้น จะเป็นข้อมูลเรคอร์ดปัจจุบัน (Active Record) ของการทำงานในคำสั่ง Select ... Endselect นั่นเอง ดังนั้นหลังคำสั่ง Endselect ถ้าเราใช้คำสั่ง Write: / customers-id,customers-name. เราก็จะได้ข้อมูลเรคอร์ดสุดท้ายที่ค้างอยู่ที่ Memory Space นั่นเอง เนื้อหาของคำสั่ง Select ยังมีต่อนะครับ ติดตามตอนต่อไปในฉบับหน้า แล้วพบกันใหม่ครับ





  • ไม่มีความคิดเห็น:

    แสดงความคิดเห็น