การเชื่อมต่อ MATLAB กับฐานข้อมูล mySQL
ในบางครั้ง เราก็จำเป็นต้องให้ MATLAB อ่านและเขียนข้อมูลจากฐานข้อมูลโดยตรง อย่างเช่นถ้าเราต้องการใช้ MATLAB ทำงานเบื้องหลังของเว็บ application หรือต้องการใช้ MATLAB ทำงานร่วมกับโปรแกรมภาษาอื่นๆ
โดยในตัวอย่างนี้ ผมจะเชื่อมต่อ MATLAB กับฐานข้อมูล mySQL ที่มาพร้อมกับโปรแกรม xampp นะครับ ดังนั้นก่อนจะเริ่มเขียนโปรแกรม เราจำเป็นจะต้องติดตั้งซอฟแวร์ต่างๆ ให้ครบก่อน ดังนี้
หรือ สำรอง
จากนั้นเปิด MATLAB ขึ้นมา และพิมพ์คำสั่งต่อไปนี้ลงใน command window
>> javaaddpath(Driver_Path)
Driver_Path หมายถึงที่อยู่ของไฟล์ JDBC Driver ที่เราโหลดมา เช่น
>> javaaddpath('C:\db_driver\driver.jar')
เพียงเท่านี้การเตรียมการทั้งหมดก็เสร็จเรียบร้อยแล้วครับ หลังจากนี้ก็เริ่มเขียนโปรแกรมติดต่อฐานข้อมูลได้เลย
หากใครรันแล้ว error หรือรันแล้วโปรแกรมไม่ทำงาน แสดงว่าคำสั่ง SQL ที่เขียนไม่ถูกต้องนะครับ ให้ตรวจเช็คคำสั่ง SQL ใหม่อีกรอบ โดยการ disp คำสั่ง SQL ออกมาดู
หากไม่มีข้อความแจ้งเตือน error แสดงว่าการเชื่อมต่อสำเร็จ
ภาษา SQL
sqlQuery = INSERT INTO TBName (Col1, Col2, Col3) VALUES ( 3 , 'Hello' , 'MATLAB' )
นี่คือรูปแบบคำสั่ง INSERT ของ SQL จะเห็นว่าตรงส่วน VALUES หากเป็นข้อมูลตัวเลข จะไม่มี single quote คร่อม ( ' ) แต่หากเป็นสตริง จะมี single quote คร่อมเอาไว้
ภาษา SQL ใน MATLAB
เราจะต้องเขียนคำสั่ง SQL ทั้งหมด ให้อยู่ในรูปแบบของสตริง ซึ่งจริงๆ มันก็ควรจะเป็นเรื่องง่ายๆ ก็แค่ใส่ single quote คร่อมคำสั่ง SQL เท่านั้น แต่............
เห็นไหมครับว่าในคำสั่ง SQL ก็มี single quote ดังนั้นมันจึงกลายเป็นว่า สตริงมาจบตรงคำว่า Hello ดังนี้
สมมุติเราใส่ single quote คร่อม
SQ = ' INSERT INTO TBName (Col1, Col2, Col3) VALUES ( 3 , 'Hello' , 'MATLAB' ) '
มันจะกลายเป็นว่า....
SQ = ' INSERT INTO TBName (Col1, Col2, Col3) VALUES ( 3 , ' Hello' , 'MATLAB' ) '
สตริงมันจะจบที่ตรงก่อนคำว่า Hello และหลัง Hello ไปจะกลายเป็น error
และถ้าหากเราเอา single quote ที่คร่อม Hello กับ MATLAB ออก มันก็จะกลายเป็นแบบนี้
SQ = ' INSERT INTO TBName (Col1, Col2, Col3) VALUES ( 3 , Hello , MATLAB ) '
คือใน MATLAB จะไม่มี error อะไร เพียงแต่ว่าหากเรา disp(SQ) ออกมาดู เราจะเห็นว่ามันเป็นแบบนี้
>> INSERT INTO TBName (Col1, Col2, Col3) VALUES ( 3 , Hello , MATLAB )
ซึ่งคุณจะเห็นว่านี่เป็นคำสั่ง SQL ที่ไม่ถูกต้อง เพราะ Hello กับ MATLAB เป็นสตริง มันจะต้องมี single quote คร่อมเอาไว้ คำสั่งนี้จึงจะทำงานได้
วิธีการแก้ปัญหาที่ถูกต้องคือ จะต้องใส่ single quote 2 อัน (ย้ำนะครับว่า single quote 2 อัน ไม่ใช่ double quote นะ) แบบนี้
SQ = ' INSERT INTO TBName (Col1, Col2, Col3) VALUES ( 3 , ''Hello'' , ''MATLAB'' ) '
หรือถ้าต้องการใส่เป็นตัวแปรในส่วนของ VALUES ให้ใช้คำสั่ง sprintf ดังนี้
SQ = sprintf('INSERT INTO TBName (Col1, Col2, Col3) VALUES ( %4.2f ,''%s'',''%s'')', A,B,C);
โดย A คือตัวแปรที่เก็บตัวเลข ส่วน B,C คือตัวแปรที่เก็บตัวอักษร
จากทั้ง 5 ตัวอย่างนี้ เราจะสังเกตุเห็นนะครับว่า MATLAB ใช้คำสั่ง exec เพื่อ compile คำสั่ง SQL ซึ่งคำสั่ง SQL ใน MATLAB ต้องอยู่ในรูปแบบของสตริงเท่านั้น และใช้คำสั่ง fetch เพื่ออ่านข้อมูลในตาราง ซึ่งผลลัพธ์ที่ได้จะอยู่ในรูปแบบตัวแปร struct ส่วนของข้อมูลเก็บไว้ในฟีลด์ที่ชื่อว่า Data
และอย่างที่ผมบอกนั่นแหละครับว่าส่วนมากจะผิดกันตรงการเขียนคำสั่ง SQL ดังนั้นหากโปรแกรมไม่ทำงาน ก็ให้มาเช็คคำสั่ง SQL ใหม่ disp ตัวแปรนั้นออกมาดู เช็คไปทีละตัวว่ามันตรงกับคำสั่งของ SQL ไหม
โดยในตัวอย่างนี้ ผมจะเชื่อมต่อ MATLAB กับฐานข้อมูล mySQL ที่มาพร้อมกับโปรแกรม xampp นะครับ ดังนั้นก่อนจะเริ่มเขียนโปรแกรม เราจำเป็นจะต้องติดตั้งซอฟแวร์ต่างๆ ให้ครบก่อน ดังนี้
1. ติดตั้ง XAMPP
ดาวน์โหลดได้ที่ https://www.apachefriends.org/index.html2. ติดตั้ง JDBC Driver ให้ MATLAB
ดาวน์โหลดได้ที่ https://www.mathworks.com/products/database/driver-installation.htmlหรือ สำรอง
จากนั้นเปิด MATLAB ขึ้นมา และพิมพ์คำสั่งต่อไปนี้ลงใน command window
>> javaaddpath(Driver_Path)
Driver_Path หมายถึงที่อยู่ของไฟล์ JDBC Driver ที่เราโหลดมา เช่น
>> javaaddpath('C:\db_driver\driver.jar')
3. สร้างฟังก์ชันเรียกใช้ JDBC Driver
ก่อนจะเชื่อมต่อฐานข้อมูลให้เรียกใช้ฟังก์ชันนี้ทุกครั้งfunction callJDBCDriver(FilePath) %%Initializing JDBC driver try import java.sql.DriverManager; javaclasspath(FilePath) driverClassName = 'com.mysql.jdbc.Driver'; %chage to full path of jar driver % if error change to default again 'com.mysql.jdbc.Driver' try %This works when the class/JAR is on the static Java classpath %Note: driver automatically registers with DriverManager java.lang.Class.forName(driverClassName); catch try %Try loading from the dynamic Java path classLoader = com.mathworks.jmi.ClassLoaderManager.getClassLoaderManager; driverClass = classLoader.loadClass(driverClassName); catch %#ok<*CTCH> try %One more attempt, using the system class-loader classLoader = java.lang.ClassLoader.getSystemClassLoader; %An alternative, using the MATLAB Main Thread's context %classLoader = %java.lang.Thread.currentThread.getContextClassLoader; driverClass = classLoader.loadClass(driverClassName); catch %One final attempt-load directly, like this: driverClass = eval(driverClassName); %#ok<*NASGU> %Or like this (if the driver name is known in advance): driverClass = com.mysql.jdbc.Driver; end end %Now manually register the driver with the DriverManager %Note: silently fails if driver is not in the static classpath DriverManager.registerDriver(driverClass.newInstance); end %continue with database processing catch error(['JDBC driver ' driverClassName ' not found!']); %do some failover activity end end
เพียงเท่านี้การเตรียมการทั้งหมดก็เสร็จเรียบร้อยแล้วครับ หลังจากนี้ก็เริ่มเขียนโปรแกรมติดต่อฐานข้อมูลได้เลย
4. การติดต่อฐานข้อมูล
4.1 การเชื่อมต่อฐานข้อมูล
JDBC_Path = 'C:\db_driver\driver.jar'; callJDBCDriver(JDBC_Path); DBName = 'test'; DBUser = 'root'; DBPass = ''; DBPort = 3306; % See on xampp sql port conn = database(DBName,DBUser,DBPass,... 'Vendor','MYSQL','Server','localhost',... 'AuthType','Server','PortNumber',DBPort); slCharacterEncoding('UTF-8');
4.2 การสร้างตาราง
ตั้งแต่หัวข้อที่ 4.2 เป็นต้นไป เป็นการใช้ MATLAB Compile คำสั่ง SQL ดังนั้นหากใครยังไม่เข้าใจคำสั่ง SQL ให้ไปศึกษาเพิ่มเติมที่ https://www.w3schools.com/sql/sql_create_table.aspหากใครรันแล้ว error หรือรันแล้วโปรแกรมไม่ทำงาน แสดงว่าคำสั่ง SQL ที่เขียนไม่ถูกต้องนะครับ ให้ตรวจเช็คคำสั่ง SQL ใหม่อีกรอบ โดยการ disp คำสั่ง SQL ออกมาดู
sqlquery = ['CREATE TABLE Persons (PersonID int, LastName varchar(255),' ,... 'FirstName varchar(255), Address varchar(255), City varchar(255))']; curs = exec(conn,sqlquery); disp(curs.Message) close(curs);
หากไม่มีข้อความแจ้งเตือน error แสดงว่าการเชื่อมต่อสำเร็จ
4.3 การเพิ่มข้อมูลลงในตาราง
หลายๆ คนจะผิดพลาดกันตรงนี้ เพราะสับสนระหว่างสตริงใน SQL และสตริงใน MATLAB ตัวอย่างเช่นภาษา SQL
sqlQuery = INSERT INTO TBName (Col1, Col2, Col3) VALUES ( 3 , 'Hello' , 'MATLAB' )
นี่คือรูปแบบคำสั่ง INSERT ของ SQL จะเห็นว่าตรงส่วน VALUES หากเป็นข้อมูลตัวเลข จะไม่มี single quote คร่อม ( ' ) แต่หากเป็นสตริง จะมี single quote คร่อมเอาไว้
ภาษา SQL ใน MATLAB
เราจะต้องเขียนคำสั่ง SQL ทั้งหมด ให้อยู่ในรูปแบบของสตริง ซึ่งจริงๆ มันก็ควรจะเป็นเรื่องง่ายๆ ก็แค่ใส่ single quote คร่อมคำสั่ง SQL เท่านั้น แต่............
เห็นไหมครับว่าในคำสั่ง SQL ก็มี single quote ดังนั้นมันจึงกลายเป็นว่า สตริงมาจบตรงคำว่า Hello ดังนี้
สมมุติเราใส่ single quote คร่อม
SQ = ' INSERT INTO TBName (Col1, Col2, Col3) VALUES ( 3 , 'Hello' , 'MATLAB' ) '
มันจะกลายเป็นว่า....
SQ = ' INSERT INTO TBName (Col1, Col2, Col3) VALUES ( 3 , ' Hello' , 'MATLAB' ) '
สตริงมันจะจบที่ตรงก่อนคำว่า Hello และหลัง Hello ไปจะกลายเป็น error
และถ้าหากเราเอา single quote ที่คร่อม Hello กับ MATLAB ออก มันก็จะกลายเป็นแบบนี้
SQ = ' INSERT INTO TBName (Col1, Col2, Col3) VALUES ( 3 , Hello , MATLAB ) '
คือใน MATLAB จะไม่มี error อะไร เพียงแต่ว่าหากเรา disp(SQ) ออกมาดู เราจะเห็นว่ามันเป็นแบบนี้
>> INSERT INTO TBName (Col1, Col2, Col3) VALUES ( 3 , Hello , MATLAB )
ซึ่งคุณจะเห็นว่านี่เป็นคำสั่ง SQL ที่ไม่ถูกต้อง เพราะ Hello กับ MATLAB เป็นสตริง มันจะต้องมี single quote คร่อมเอาไว้ คำสั่งนี้จึงจะทำงานได้
วิธีการแก้ปัญหาที่ถูกต้องคือ จะต้องใส่ single quote 2 อัน (ย้ำนะครับว่า single quote 2 อัน ไม่ใช่ double quote นะ) แบบนี้
SQ = ' INSERT INTO TBName (Col1, Col2, Col3) VALUES ( 3 , ''Hello'' , ''MATLAB'' ) '
หรือถ้าต้องการใส่เป็นตัวแปรในส่วนของ VALUES ให้ใช้คำสั่ง sprintf ดังนี้
SQ = sprintf('INSERT INTO TBName (Col1, Col2, Col3) VALUES ( %4.2f ,''%s'',''%s'')', A,B,C);
โดย A คือตัวแปรที่เก็บตัวเลข ส่วน B,C คือตัวแปรที่เก็บตัวอักษร
sqlquery = ['INSERT INTO Persons (PersonID, LastName, FirstName, Address, City)',... ' VALUES (1, ''Thailand'', ''MATLAB'', ''KhonKaen'', ''KhonKaen'')']; curs = exec(conn,sqlquery); disp(curs.Message) close(curs);
4.4 การแก้ไขข้อมูลในตาราง
sqlquery = ['UPDATE Persons SET PersonID = 2, LastName = ''MATLAB'', ',... 'FirstName = ''Facebook'', Address = ''191/47'', ',... 'City = ''KhonKaen'' WHERE PersonID = 2']; curs = exec(conn,sqlquery); disp(curs.Message) close(curs);
4.5 การอ่านข้อมูลในตาราง
sqlquery = 'SELECT * FROM Persons'; curs = exec(conn,sqlquery); disp(curs.Message) raws = fetch(curs); Data = raws.Data; disp(Data) close(curs);
4.6 การลบข้อมูลในตาราง
sqlquery = 'DELETE FROM Persons WHERE PersonID = 2'; curs = exec(conn,sqlquery); disp(curs.Message) close(curs);
จากทั้ง 5 ตัวอย่างนี้ เราจะสังเกตุเห็นนะครับว่า MATLAB ใช้คำสั่ง exec เพื่อ compile คำสั่ง SQL ซึ่งคำสั่ง SQL ใน MATLAB ต้องอยู่ในรูปแบบของสตริงเท่านั้น และใช้คำสั่ง fetch เพื่ออ่านข้อมูลในตาราง ซึ่งผลลัพธ์ที่ได้จะอยู่ในรูปแบบตัวแปร struct ส่วนของข้อมูลเก็บไว้ในฟีลด์ที่ชื่อว่า Data
และอย่างที่ผมบอกนั่นแหละครับว่าส่วนมากจะผิดกันตรงการเขียนคำสั่ง SQL ดังนั้นหากโปรแกรมไม่ทำงาน ก็ให้มาเช็คคำสั่ง SQL ใหม่ disp ตัวแปรนั้นออกมาดู เช็คไปทีละตัวว่ามันตรงกับคำสั่งของ SQL ไหม