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


1,031 ผู้ชม


ภาคต่อของการเขียนโปรแกรมภาษา ABAP เจาะลึกคำสั่ง Open SQL

พื้นที่โฆษณา  
สนใจลงโฆษณา ติดต่อ โทร.0-2642-3400 ต่อ 4613

ภาคต่อของการเขียนโปรแกรมภาษา ABAP เจาะลึกคำสั่ง Open SQL

ต่อเนื่องจากฉบับที่แล้วนะครับ สำหรับคำสั่ง Select ในกรณีที่ไม่มีข้อมูลที่ต้องการ จากการที่ DB Interface ส่งคำสั่ง Native SQL ไปให้ Database Server ประมวลผล ดังนั้นก็จะไม่มีข้อมูลส่งกลับมาที่ Result Set ระบบก็จะไม่เรียกคำสั่งภายในบล็อกของ Select ... Endselect ขึ้นมาทำงานแต่อย่างใด แต่จะไปต่อที่คำสั่งถัดจาก Endselect โดยทันที ดังนั้นโดยปกติแล้ว หลังคำสั่ง Endselect จึงควรมีการเช็กว่ามีข้อมูลใน Result Set ที่จะอ่านเข้ามาหรือไม่ โดยให้เราเช็กจากตัวแปรระบบที่ชื่อ sy-subrc ซึ่งเป็นตัวแปรระบบที่เก็บค่าการทำงานของคำสั่ง ABAP ล่าสุด ซึ่งถ้าการทำงานสำเร็จก็จะได้ค่า 0 แต่ถ้าไม่สำเร็จก็จะได้ค่าที่มากกว่า 0 เช่น

Tables customers.
Select * from customers.
Write: / customers-id, customers-name.
Endselect.
If sy-subrc <> 0.
Write: / 'No data found'.
Endif.

โดยที่ถ้ามีข้อมูลในตาราง customers ที่ฐานข้อมูล เราก็จะได้ข้อมูลของตาราง customers ทั้งหมดที่หน้าจอ แต่ถ้าไม่มีข้อมูลในตาราง customers ที่ฐานข้อมูล เราก็จะได้ข้อความ No data found ออกมาแทน นอกจากนี้เรายังสามารถใช้ตัวแปรระบบ sy-dbcnt ซึ่งเป็นตัวแปรระบบที่ให้ค่ารอบในการวนลูปของคำสั่ง Select ... Endselect (เหมือนกับตัวแปรระบบ sy-index ในบล็อกของคำสั่ง Do ... Enddo) ดังนั้นถ้าเราต้องการทราบว่ามีกี่เรคอร์ดที่คำสั่ง Select ... Endselect อ่านขึ้นมาได้นั้น เราก็สามารถใช้ตัวแปรระบบ sy-dbcnt หลังคำสั่ง Endselect ได้ดังนี้

Tables customers.
Select * from customers.
Write: / customers-id, customers-name.
Endselect.
If sy-subrc <> 0.
Write: / 'No data found'.
Else.
Write: / sy-dbcnt, 'Record(s) read'.
Endif.

จะเห็นได้ว่าคำสั่ง Select ... Endselect นี้ใช้ในการวนลูป เพื่ออ่านข้อมูลในตารางของฐานข้อมูล ในลักษณะของ Multiple Record แต่ถ้าเราต้องการอ่านข้อมูลเพียงเรคอร์ดเดียว หรือที่เรียกว่า Single Record เราจะใช้ออปชัน single ในคำสั่ง Select เช่น

Tables customers.
Select single * from customers where id = 1.
If sy-subrc = 0.
Write: / customers-id, customers-name.
Else.
Write: / 'No data found'.
Endif.

โดยที่คำสั่ง Select single ... จะไม่ปิดด้วย Endselect เพราะเป็นการอ่านข้อมูลเพียงแค่เรคอร์ดเดียวนั่นเอง ส่วนการทำงานของคำสั่ง Select single นั้นยังคงเป็นเช่นเดิม ก็คือ DB Interface จะแปลงคำสั่ง Open SQL นี้ให้เป็น Native SQL เพื่อส่งไป Database Server เพื่ออ่านข้อมูลที่ฐานข้อมูล จากนั้นผลลัพธ์ที่ได้จะส่งมาที่ Result Set เพียงเรคอร์ดเดียว พร้อมกับมี Pointer ชี้อยู่ที่เรคอร์ดนั้น
จากนั้นคำสั่ง Select single ... ก็จะอ่านข้อมูลจาก Result Set นี้ไปไว้ที่ Table Structure ที่ชื่อ customers ที่ Memory Space ต่อไป โดยที่ถ้ามีข้อมูลที่อ่านได้จาก Result Set ระบบก็จะให้ค่า 0 ให้กับตัวแปรระบบ sy-subrc แต่ถ้าไม่มีข้อมูล ค่า sy-subrc ก็จะได้ค่าที่มากกว่า 0
ดังนั้นหลังจากอ่านข้อมูลจากคำสั่ง Select single ... แล้ว เราควรจะเช็กค่าตัวแปร sy-subrc ด้วยเสมอ มิฉะนั้นเราอาจเอาข้อมูลที่ค้างอยู่ที่ Table Structure ใน Memory Space ไปทำงานอย่างผิดๆ
สำหรับรูปแบบของ Where Clause ในคำสั่ง Select นั้น จะมีรูปแบบเป็นชื่อฟิลด์ตามด้วย Operator ต่างๆ เช่น

Select * from customers where id = 1. หรือ
Select * from customers where id > 1 and city = 'Bangkok'.

นอกจากนี้เรายังสามารถใช้ออปชัน Between หรือ in ใน Where Clause ได้เช่น

Select * from customers where id between 1 and 9. หรือ
Select * from customers where city in ('Bangkok', 'Rayong').

ก็คือต้องการอ่านข้อมูลของตาราง customers โดยมีเงื่อนไขคือ ค่าฟิลด์ id อยู่ระหว่าง 1 ถึง 9 และค่าของฟิลด์ city มีค่าเป็น 'Bangkok' หรือ 'Rayong' ตามลำดับ

อ่านข้อมูลเฉพาะบางฟิลด์

การอ่านข้อมูลทุกฟิลด์หรือทุกคอลัมน์จากคำสั่ง Select * ... หรือ Select single * ... นั้น ถ้าพิจารณาในด้านของประสิทธิภาพแล้วดูจะไม่ค่อยดีสักเท่าไร เพราะมีการอ่านข้อมูลทุกฟิลด์จาก Database Server มาไว้ที่ Result Set ถ้าเรานับจำนวนข้อมูลเป็นไบต์ที่มีการโอนย้ายจาก Database Server ไปที่ Application Server ก็มากพอสมควร ยิ่งถ้ามีข้อมูลหลายเรคอร์ด ปริมาณการโอนย้ายคงมหาศาลเลยทีเดียว และที่สำคัญเรามักจะใช้ข้อมูลที่อ่านขึ้นมาได้เพียงแค่ไม่กี่ฟิลด์เท่านั้นเอง ดังนั้นถ้าอยากเขียนโปรแกรมให้มีประสิทธิภาพ เราก็ควรหลีกเลี่ยงการอ่านข้อมูลทุกฟิลด์จากคำสั่ง Select * ... หรือ Select single * ... โดยให้ทำการอ่านข้อมูลเฉพาะฟิลด์ที่เราต้องการเท่านั้น เช่น สมมติว่าเราต้องการแสดงข้อมูล id และ name ของตาราง customers เราสามารถเขียนโปรแกรมได้ดังนี้

Data: v_id like customers-id,
V_name like customers-name.
Select id name
Into (v_id, v_name)
From customers.
Write: / v_id, v_name.
Endselect.

โดยที่ DB Interface จะแปลงคำสั่ง Select id name ... ให้เป็น Select id, name from customers; เพื่อส่งไปให้ Database Server (ORACLE RDBMS) จากนั้น Database Server ก็จะส่งข้อมูลกลับไปที่ Result Set เฉพาะฟิลด์ที่ต้องการเท่านั้น ดังรูปที่ 1
รูปที่ 1 ผลจากการรันคำสั่ง Select id name into (v_id, v-name)

จากนั้นคำสั่ง Select id name into (v_id, v_name) ... ก็จะถูกนำมารัน ทำให้อ่านข้อมูลที่ Pointer ชี้อยู่ไปไว้ที่ตัวแปร v_id และ v_name ที่ Memory Space ตามลำดับ ส่วนการทำงานของคำสั่ง Write และ Endselect นั้นยังคงเป็นเช่นเดิม ซึ่งจะเห็นได้ว่า เมื่อใดก็ตามที่เราระบุออปชัน into ในคำสั่ง Select เราก็ไม่จำเป็นที่จะต้องสร้าง Table Structure ขึ้นมาที่ Memory Space แต่อย่างใด เพราะ Table Structure ที่สร้างขึ้นมาจากคำสั่ง Tables นั้นรองรับการทำงานของคำสั่ง Select * ... หรือ Select single * ... ที่ไม่มีการระบุออปชัน into เท่านั้น


PC Magazine

ฉบับที่ 47 ธันวาคม 2545
อ่านบทความอื่นๆ >>

อัพเดทล่าสุด