November 30, 2012

Haskell: เกร็ดน่ารู้ก่อนเริ่มใช้งาน

จากตอนที่ผ่านมา จะเห็นว่าแบบ interactive นั้นไม่ต้องเขียน main = do ขึ้นต้น นั่นเป็นเพราะว่าเมื่อเริ่ม ghci เราจะเข้ามาอยู่ด้านในของ main ที่ว่านั้นทันที ซึ่งการเขียน code ภายใน main จะมีกฏที่ต่างออกไปเล็กน้อยด้วย

ความสะดวกอย่างอื่นๆ ของตัว interactive
  • แสดงผลลัพท์จากคำสั่งที่พิมพ์เข้าไปทันที (read-eval-print-loop)
  • ทำ keyword completion ด้วย tab
  • macro สำหรับการ debug โดยใช้เครื่องหมาย colon ตามด้วย command (เช่น :q ที่ได้เจอไปแล้ว)
อย่างไรก็ตาม ตัว interactive นั้นไม่รองรับการเขียนหลายบรรทัดเป็นค่าเริ่มต้น ถ้าต้องการเขียนหลายบรรทัด ให้เริ่มด้วย :{ และขึ้นบรรทัดใหม่ แล้วค่อยเริ่มส่วน code เรียบร้อยแล้วจบด้วยบรรทัดที่มีแต่ :} ครับ

อนึ่ง เครื่องหมายหน้าบรรทัดที่บอกว่ากำลังอยู่ใน interactive จะเขียนว่า Prelude> ซึ่งต่อไปเมื่อทำการ load module เยอะๆ แล้ว ข้อความตรงนี้จะเปลี่ยนไปบอกว่า load อะไรมาแล้วบ้าง (ซึ่งอาจจะยาวมาก) ดังนั้น ที่นี้จะใช้แค่ ghci> แทน (สามารถ set ให้เป็นข้อความนี้ได้ด้วย :set prompt "ghci>" ครับ)



ส่วนการเขียนโปรแกรมเก็บเป็นไฟล์นั้น นอกจากจะใช้ ghc เพื่อ compile เป็น binary code ออกมาทดสอบแล้ว ยังมี runhaskell ที่อ่านไฟล์แล้วรันให้ทันทีโดยไม่สร้างไฟล์พวก .o, .hi หรือตัว binary code ให้ แน่นอนว่ามันจะทำงานได้ช้ากว่าแบบ binary code เพราะไม่โดน optimize ด้วยตัว compiler และยังต้องแปลใหม่ทุกครั้งที่เรียกใช้ครับ

ก็เลือกใช้ ghci, ghc และ runhaskell กันตามความเหมาะสมนะครับ



ด้านนามสกุลไฟล์นอกจาก .hs แล้ว ก็มี .lhs ซึ่งเป็นไฟล์ที่เน้นการเขียนโปรแกรมแบบเอกสาร แล้วแทรก code ตามจุดต่างๆ (literate programming) ตัวอย่างก็เช่น


โปรแกรมนี้จะแสดงผลลัพท์เช่นเดียวกับตอนที่แล้ว อย่างไรก็ตามส่วนที่อธิบายโปรแกรมนั้น ไม่ได้ส่งผลให้เกิดความแตกต่างของ binary code แต่อย่างใด

ส่วนการ comment source ใน Haskell แบบบรรทัดเดียวใช้ -- เพื่อ comment ข้อความจนจบบรรทัด และแบบหลายบรรทัดใช้ {- กับ -} ครอบส่วนที่ต้องการ comment

ในที่นี้จะไม่ใช้ comment ให้ดู เนื่องจากตัว syntax highlighter ไม่ระบายสีให้ครับ :P

November 29, 2012

Haskell: สวัสดีโลก

1990 มาตรฐานภาษา Haskell 1.0 ปรากฏตัว
1998 รวบรวมมาตรฐานภาษารุ่นก่อนๆ ได้เป็น Haskell 98
2003 GHC เครื่องมือแปลภาษา Haskell ได้รับความนิยมจนเป็นมาตรฐานกลายๆ
2010 ตัวภาษาเดินทางมาถึงรุ่น Haskell 2010

ชื่อภาษาตั้งเพื่อเป็นเกียรติแก่ Haskell Curry นักคณิตศาสตร์ผู้บุกเบิก combinatory logic ครับ



Haskell เป็นภาษา purely functional ซึ่งทำให้เราไม่สามารถเปลี่ยนค่าตัวแปรหลังจากที่ประกาศมันได้ ส่งผลให้การคำนวณซ้ำแบบ loop ต้องเปลี่ยนไปเขียนในรูป recursion หรือ list comprehension แทน ซึ่งจะช่วยลด side effect อย่างการแชร์ตัวแปรจากที่เดียวกันได้ นอกจากนี้ตัวภาษายังเป็นแบบ lazy evaluation คือจะทำการคำนวณให้เมื่อขอดูผลลัพท์เท่านั้นครับ

โหลดโปรแกรม haskell-platform มาติดตั้งได้จากที่นี่ รองรับทั้ง Windows, Mac และ Linux (สำหรับ Debian ติดตั้งจาก apt-get ได้ด้วย) หรือจะไปทดลองเล่น intepreter ขนาดย่อมผ่านหน้าเว็บก่อนก็ได้



Haskell นั้นมาพร้อมกับ compiler และ interpreter ในตัว ซึ่งทั้งสองแบบนี้จะมีการทำงานแตกต่างกันเล็กน้อย ว่าแล้วก็มาลอง hello กัน โดยเริ่มที่แบบ interpreter ก่อน โดยพิมพ์

เพื่อเข้าสู่ Haskell interpreter ซึ่งมีข้อความต้อนรับดังนี้

พิมพ์

ก็จะพบกับข้อความทักทาย เรียบร้อยแล้วออกโปรแกรมโดยพิมพ์ :q [Enter] หรือป้อน EOF ก็ได้

ส่วนแบบที่ต้อง compile สร้างไฟล์ใหม่ที่มีข้อความดังนี้

เซฟเป็นไฟล์ hello.hs แล้วสั่ง

จะได้ไฟล์ hello มา (ต่างจาก compiler อย่าง gcc ที่จะได้ไฟล์ a.out) และเรียกโปรแกรมโดย

ก็เป็นอันเสร็จพิธี

November 22, 2012

PHP: PDO กับฐานข้อมูล

ในการใช้ PHP ทำงานร่วมกับฐานข้อมูล จำเป็นต้องรู้ภาษา SQL เสียก่อน และต้องรู้ด้วยว่า ฐานข้อมูลที่ต้องทำงานด้วยนั้นเป็นระบบไหน เพราะ PHP มีคำสั่งเฉพาะสำหรับฐานข้อมูลแต่ละระบบแยกกันอยู่

แต่เมื่อมีเทคโนโลยีมากขึ้นระบบฐานข้อมูลมีความหลากหลายมากขึ้น ความคล่องตัวในการย้ายฐานข้อมูลจากระบบหนึ่งไปยังอีกระบบหนึ่งก็ยุ่งยากขึ้น ทาง PHP จึงสร้าง extension ชื่อ PDO (PHP Data Objects) ขึ้นมาเพื่อเป็นตัวกลางในการจัดการฐานข้อมูล โดยโปรแกรมเมอร์แทบไม่ต้องสนใจว่า ระบบฐานข้อมูลที่จะทำงานร่วมกันเป็นแบบไหน

การเชื่อมต่อกับระบบฐานข้อมูลผ่าน PDO ก็ให้สร้างออปเจ็กของคลาสขึ้นมา ตัวอย่างข้างต้นใช้ MySQL แต่ถ้าต้องการเปลี่ยนเป็นอย่างอื่นก็แก้ไขบรรทัดที่ 12 ให้เป็นระบบฐานข้อมูลนั้น ๆ หากไม่มีการใช้คำสั่ง SQL ที่จำเพาะต่อระบบฐานข้อมูลนั้น ๆ ก็จะไม่ต้องแก้ไขโค้ดในส่วนอื่น ๆ อีก ส่วนการปิดการเชื่อมต่อนั้น ตามหลักแล้ว PHP จะปิดการเชื่อมต่อให้โดยอัตโนมัติเมื่อจบสคริปท์ แต่หากต้องการสั่งเองก็ใช้ เมื่อเชื่อมต่อกับฐานข้อมูลได้แล้ว ก็สามารถใช้คำสั่ง SQL จัดการกับฐานข้อมูลได้ 2 วิธี คือ
  • สั่งโดยตรงผ่านฟังชั่น exec() และ query()
  • ใช้ฟังชั่น prepare() และ excute()

November 12, 2012

SQL: สร้าง เพิ่ม ลบ อัพเดทข้อมูลในฐานข้อมูล

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

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

นอกจากนี้ ยังต้องคำนึงด้วยว่าระบบฐานข้อมูลที่ใช้อยู่เป็นตัวไหน เพราะคำสั่งนี้บางส่วนในบางระบบจะใช้ไม่เหมือนกัน (อย่างเช่นการกำหนด primary key และ การเพิ่มค่าอัตโนมัติในตัวอย่าง) ตอนนี้ก็จะมีตาราง application เปล่า ๆ ขึ้นมาอันหนึ่ง
idnamecategorydeveloperyear
การเพิ่มข้อมูล (แถว) เข้าตารางจะใช้คำสั่ง INSERT INTO ในที่นี้คอลัมภ์ id จะเพิ่มโดยอัตโนมัติ (auto_increment) ถ้าส่งค่า null ไประบบฐานข้อมูลจะใส่ค่าถัดไปให้โดยอัตโนมัติ และถ้าต้องการเพิ่มข้อมูลที่ละหลาย ๆ แถวก็สามารถใส่ค่าของ VALUES ลงไปหลาย ๆ ชุดได้เช่นกัน ผลที่ได้จะเป็น
idnamecategorydeveloperyear
1WindowsOSMicrosoft1985
2OS XOSApple Inc.2001
3Microsoft OfficeOffice SuiteMicrosoft1990
4Libre OfficeOffice SuiteThe Document Foundation2011
5Adobe PhotoshopGraphic EditorAdobe1990
6GIMPGraphic EditorThe GIMP Development Team1996
7FirefoxBrowserMozilla2004
ถ้าตารางนั้นมีข้อมูลเริ่มต้นอยู่ หรือไม่จำเป็นต้องใส่ค่าลงไปได้ สามารถที่จะระบุเฉพาะคอลัมภ์ที่ต้องการใส่ข้อมูลลงไปได้เช่นเดียวกัน ผลที่ได้จะเป็น
idnamecategorydeveloperyear
1WindowsOSMicrosoft1985
2OS XOSApple Inc.2001
3Microsoft OfficeOffice SuiteMicrosoft1990
4Libre OfficeOffice SuiteThe Document Foundation2011
5Adobe PhotoshopGraphic EditorAdobe1990
6GIMPGraphic EditorThe GIMP Development Team1996
7FirefoxBrowserMozilla2004
8Chromium  2008
ส่วนการแก้ไขข้อมูลนั้นจะใช้ UPDATE ผลที่ได้จะเป็น
idnamecategorydeveloperyear
1WindowsOSMicrosoft1985
2OS XOSApple Inc.2001
3Microsoft OfficeOffice SuiteMicrosoft1990
4Libre OfficeOffice SuiteThe Document Foundation2011
5Adobe PhotoshopGraphic EditorAdobe1990
6GIMPGraphic EditorThe GIMP Development Team1996
7FirefoxBrowserMozilla2004
8Google ChromeBrowserGoogle Inc.2008
สิ่งที่ควรจำให้ขึ้นใจคือ จะแก้ไขข้อมูลต้องมี WHERE เสมอ ไม่เช่นนั้นจะเป็นการแก้ไขข้อมูลทั้งตาราง! และควรจะใช้เงื่อนไขของ WHERE อย่างรอบคอบ เพื่อไม่ให้ข้อมูลที่ไม่เกี่ยวข้องได้รับผลกระทบ

ส่วนการลบข้อมูลก็จะใช้ DELETE ซึ่งจำเป็นต้องมี WHERE เช่นกัน และที่สำคัญคือถ้าใช้ WHERE ไม่รอบคอบ หรือไม่ใช้ ข้อมูลอาจจะหายไปทั้งตารางได้เช่นกัน
idnamecategorydeveloperyear
1WindowsOSMicrosoft1985
2OS XOSApple Inc.2001
5Adobe PhotoshopGraphic EditorAdobe1990
6GIMPGraphic EditorThe GIMP Development Team1996
7FirefoxBrowserMozilla2004
8Google ChromeBrowserGoogle Inc.2008
แม้ว่าจะใช้ DELETE ลบข้อมูลทั้งตารางทิ้งไป แต่โครงสร้างตาราง ค่า index (ที่ใช้ในการค้นหาข้อมูล) รวมถึงค่าคุณลักษณะ (attribute) ต่าง ๆ ของตารางยังคงอยู่ ไม่ได้ถูกลบไปด้วย ตามด้วย ผลจะเป็น
idnamecategorydeveloperyear
9Internet ExplorerOSMicrosoft1995
แต่หากต้องการจะลบข้อมูลในตารางทิ้งจริง ๆ แนะนำให้ใช้ TRUNCATE เพราะมันรวดเร็วกว่า และใช้ทรัพยากรน้อยกว่า หากจะลบตารางทั้งตารางทิ้งจะใช้คำสั่ง DROP ตาราง application ทั้งตารางรวมทั้งโครงสร้างจะหายไปจากฐานข้อมูล ถ้าจะใช้ตารางนี้อีก ต้องสร้างตารางขึ้นมาใหม่เสียก่อน

นอกจากลบตารางทิ้งแล้ว DROP ยังสามารถลบฐานข้อมูลทั้งฐานข้อมูลทิ้งได้เช่นกัน (ทั้งนี้ขึ้นอยู่กับสิทธิ์ในการเข้าถึงฐานข้อมูลของบัญชีผู้ใช้อันนั้น ๆ ด้วย ว่าสามารถทำได้ถึงขั้นไหน)

November 5, 2012

SQL: ดึงข้อมูลจากฐานข้อมูลด้วย SELECT

SQL (Structured Query Language - ภาษาสอบถามเชิงโครงสร้าง) เป็นภาษาสำหรับจัดการฐานข้อมูลที่นิยมใช้กันมากในปัจจุบัน

SQL พัฒนาที่ IBM โดย Donald D. Chamberlin และ Raymond F. Boyce ในปี ค.ศ. 1970 โดยมีแนวคิดบางส่วนมาจาก Edgar F. Codd เพื่อใช้กับระบบฐานข้อมูล System R

เดิม SQL จะใช้ชื่อว่า SEQUEL (Structured English Query Language) แต่ดันมีปัญหาเรื่องเครื่องหมายการค้า เลยเปลี่ยนชื่อเป็น SQL ซึ่งอ่านได้ทั้ง เอส-คิว-แอล, ซี-เควล และ ซี-ควล ตามชอบใจ

ระบบฐานข้อมูลส่วนใหญ่ ไม่ว่าจะเป็น MySQL, PostgreSQL, SQL Server, Access, Oracle, DB2 หรือ SQLite ก็ใช้ SQL ในการจัดการข้อมูลทั้งสิ้น

แต่... แม้ว่าระบบฐานข้อมูลเหล่านี้จะใช้ SQL ในการจัดการเหมือนกัน แต่รายละเอียดบางคำสั่งย่อย ๆ บางคำสั่งอาจจะแตกต่างกัน หากผลที่ได้ไม่ได้ออกมาตามต้องการ ให้คิดถึงจุดนี้ด้วย

สำหรับข้อมูลที่ใช้จะใช้ข้อมูลตามนี้ ขอตั้งชื่อตารางว่า application
idnamecategorydeveloperyear
1WindowsOSMicrosoft1985
2OS XOSApple Inc.2001
3Microsoft OfficeOffice SuiteMicrosoft1990
4Libre OfficeOffice SuiteThe Document Foundation2011
5Adobe PhotoshopGraphic EditorAdobe1990
6GIMPGraphic EditorThe GIMP Development Team1996
การนำข้อมูลมาแสดงจะใช้ SELECT ... FROM ... เป็นหลัก โดยอาจจะกำหนดเงื่อนไขผ่านทาง WHERE (ที่จริงแล้วคำสั่ง SQL จะใช้ตัวพิมพ์เล็ก หรือตัวพิมพ์ใหญ่ก็ให้ผลเหมือนกัน เพียงแต่ใช้ตัวพิมพ์ใหญ่จะอ่านได้เข้าใจง่ายกว่า) ผลที่ได้จะเหมือนกับตารางด้านบน คือ เอาข้อมูลทุกอย่างมาแสดง อันนี้เลือกเอาจะเฉพาะคอลัมภ์ name กับ year มาแสดง
nameyear
Windows1985
OS X2001
Microsoft Office1990
Libre Office2011
Adobe Photoshop1990
GIMP1996
อันนี้จะแสดงข้อมูลที่ไม่ซ้ำกันเท่านั้น ที่ซ้ำตัดทิ้งไป อาจะใช้หาว่า ลูกค้าของบริษัทเป็นคนจังหวัดใดบ้าง เป็นต้น
category
OS
Office Suite
Graphic Editor
แต่ถ้าหากจะกำหนดเงื่อนไขว่าเอาข้อมูลที่มีอย่างนั้นอย่างนี้จะต้องใช้ WHERE เข้าช่วย โดยใช้การเปรียบเทียบทั่ว ๆ ไป รวมทั้ง BETWEEN (ระหว่างค่า 2 ค่า) LIKE (ค้นหาโดยใช้ pattern) และ IN (ข้อมูลในคอลัมภ์เป็นค่าใดค่าหนึ่งในนี้)

หมายเหตุ: สำหรับการเปรียบเทียบ ไม่เท่ากับ ระบบฐานข้อมูลบางตัวใช้ <> แต่บางตัวใช้ != ผลที่ได้คือ จะแสดงเฉพาะแอพที่เปิดตัวตั้งแต่ปี 2000 ขึ้นไป
idnamecategorydeveloperyear
2OS XOSApple Inc.2001
4Libre OfficeOffice SuiteThe Document Foundation2011
หากจะให้ค้นหาข้อมูลจาก 2 คอลัมภ์ จะต้องใช้ AND (และ) หรือ OR (หรือ) เพิ่มต่อจาก WHERE หมายเหตุ: ถ้าสังเกต จะเห็นว่า การเปรียบเทียบ เท่ากับ ใน SQL จะใช้เครื่องหมายเท่ากับเพียงอันเดียว แทนที่จะเป็นสองอันแบบหลาย ๆ ภาษา ผลที่ได้คือ แสดงข้อมูลจะเฉพาะที่ปีต่ำกว่า 2000 และอยู่ในหมวด OS เท่านั้น
idnamecategorydeveloperyear
1WindowsOSMicrosoft1985
หากพบว่า ข้อมูลที่อยู่ในฐานข้อมูลเรียงไม่ถูกใจ สามารถสั่งเรียงข้อมูลใหม่ได้โดยผ่าน ORDER BY ผลที่ได้คือ ข้อมูลที่ได้จะเรียงตามปีจากน้อยไปหามาก (ASC) แต่ถ้าจะให้เรียงจากมากไปหาน้อยจะใช้ DESC
namecategorydeveloperyear
WindowsOSMicrosoft1985
Microsoft OfficeOffice SuiteMicrosoft1990
Adobe PhotoshopGraphic EditorAdobe1990
GIMPGraphic EditorThe GIMP Development Team1996
OS XOSApple Inc.2001
Libre OfficeOffice SuiteThe Document Foundation2011
สำหรับข้อมูลในฐานข้อมูลนั้นจะยังคงเรียงอยู่เหมือนเดิม คำสั่งนี้ใช้เฉพาะการดึงข้อมูลมาแสดงเท่านั้น ถ้าลองสั่ง SELECT * FROM application ดู ผลจะได้เหมือนกับตาราางแรกสุด

ถ้าสังเกตดูภาษา SQL จะอ่านเข้าใจง่าย และคล้ายภาษาอังกฤษมาก