13-5 洏MATLABおwi蚹

上一節說名了如何使用MATLAB對資料庫進行查詢,本節將說明如何對資料庫進行改變,包含新增、修改與刪除。

簡單地說,MATLAB 能夠經由 ODBC 和對對資料庫進行操控,因此所有 SQL 命令能達到的功能,MATLAB 也都能經由下達 SQL 命令來做到。此外,MATLAB 的資料庫工具箱也提供了另外一些命令,能夠對資料庫進行修改。

在嘗試本節所提供的範例前,你必須先以手動的方式來設定 DSN,請將資料來源名稱 dsnScore02 指到本機位置的 score02.mdb。同時在以下的範例中,每次在進行資料庫存取前,我們會將 score01.mdb 的內容拷貝到 score02.mdb,以避免因為多個範例程式碼的執行先後順序不同,造成所得結果和本書描述不一致的情況。

首先,我們來看看如何經由 SQL 命令來新增一筆資料到資料庫的。下面這個範例,將新增一筆姓名為「大力水手」的資料,對應的 SQL 命令是

INSERT INTO score (studentID, studentName, final) VALUES (''00'', ''大力水手'', 100)

程式碼如下。

Example 1: 13-與資料庫的整合/insertData01.mcopyfile('score01.mdb', 'score02.mdb'); % 將 score01.mdb 拷貝到 score02.mdb dsn = 'dsnScore02'; % 設定資料來源名稱(指到 score02.mdb) logintimeout(5); % 設定嘗試連結資料庫的時間 conn = database(dsn, '', ''); % 連結資料庫 % 設定新增資料所用的 SQL 命令 sql = 'INSERT INTO score (studentID, studentName, final) VALUES (''00'', ''大力水手'', 100)'; cursor = exec(conn, sql); % 執行 SQL 命令 % 設定查詢資料用的 SQL 命令 sql = 'select * from score'; cursor = exec(conn, sql); cursor = fetch(cursor); newScore = cursor.data % 顯示更新後 final 欄位的資料 close(cursor); % 結束 cursor 物件 close(conn); % 結束資料庫連結newScore = '914340' '傅思為' [82] [ 93] [ 87] [ 77] [ 80] [0] '916310' '薛博謙' [83] [ 93] [ 93] [ 99] [ 80] [0] '882545' '王儀蓁' [86] [ 96] [ 92] [ 99] [ 77] [0] '8802142' '許肇凌' [86] [ 96] [ 92] [ 90] [ 78] [0] '914358' '徐茂原' [87] [ 93] [ 87] [ 90] [ 80] [0] '898316' '李俊仁' [87] [ 95] [ 94] [ 99] [ 88] [0] '914370' '陳晴' [88] [ 93] [ 93] [ 95] [ 79] [0] '916716' '鍾綸' [88] [ 94] [ 87] [ 99] [ 77] [0] '914307' '謝明峰' [89] [ 93] [ 93] [ 90] [ 77] [0] '882548' '蘇金龍' [89] [ 94] [ 90] [ 99] [ 78] [0] '916701' '羅瑞麟' [90] [ 94] [ 90] [ 90] [ 77] [0] '916717' '林青慧' [90] [ 97] [ 92] [ 99] [ 80] [0] '00' '大力水手' [ 0] [NaN] [NaN] [NaN] [100] [0]

由於我們並沒有指定每一個欄位的值,所以這些欄位的值會由資料庫當初所設定的欄位預設值所取代,如果這些資料庫欄位沒有預設值,MATLAB 抓回來的資料就會出現 NaN。

接著,我們來看看如何經由 SQL 命令來修改資料庫。下面這個範例,將所有期末考分數(final 欄位)大於或等於 80 分的同學,直接調成 100 分,對應的 SQL 命令是

UPDATE score SET final=100 WHERE final>=80

程式碼如下。

Example 2: 13-與資料庫的整合/updateData01.mcopyfile('score01.mdb', 'score02.mdb'); % 將 score01.mdb 拷貝到 score02.mdb dsn = 'dsnScore02'; % 設定資料來源名稱(指到 score02.mdb) logintimeout(5); % 設定嘗試連結資料庫的時間 conn = database(dsn, '', ''); % 連結資料庫 % 設定更新資料所用的 SQL 命令 sql = 'UPDATE score SET final=100 WHERE final>=80'; cursor = exec(conn, sql); % 執行 SQL 命令 % 設定進行資料查詢的 SQL 命令 sql = 'select studentName, final from score'; % 設定 SQL 命令 cursor = exec(conn, sql); cursor = fetch(cursor); newScore = cursor.data % 顯示更新後 final 欄位的資料 close(cursor); % 結束 cursor 物件 close(conn); % 結束資料庫連結newScore = '傅思為' [100] '薛博謙' [100] '王儀蓁' [ 77] '許肇凌' [ 78] '徐茂原' [100] '李俊仁' [100] '陳晴' [ 79] '鍾綸' [ 77] '謝明峰' [ 77] '蘇金龍' [ 78] '羅瑞麟' [ 77] '林青慧' [100]

在上述範例中,有四個人的期末考成績(final 欄位)被修改為 100 分。

我們也可已經由SQL 命令來刪除資料。下面這個範例,將所有期末考分數(final 欄位)小於 80 分的同學,直接刪除,對應的 SQL 命令是

DELETE FROM score WHERE final<80

程式碼如下。

Example 3: 13-與資料庫的整合/deleteData01.mcopyfile('score01.mdb', 'score02.mdb'); % 將 score01.mdb 拷貝到 score02.mdb dsn = 'dsnScore02'; % 設定資料來源名稱(指到 score02.mdb) logintimeout(5); % 設定嘗試連結資料庫的時間 conn = database(dsn, '', ''); % 連結資料庫 % 設定刪除資料所用的 SQL 命令 sql = 'DELETE FROM score WHERE final<80'; cursor = exec(conn, sql); % 設定進行資料查詢的 SQL 命令 sql = 'select studentName, final from score'; cursor = exec(conn, sql); cursor = fetch(cursor); newScore = cursor.data % 顯示更新後 final 欄位的資料 close(cursor); % 結束 cursor 物件 close(conn); % 結束資料庫連結newScore = '傅思為' [80] '薛博謙' [80] '徐茂原' [80] '李俊仁' [88] '林青慧' [80]

在上述範例中,原先資料庫有 12 筆資料,經過刪除後,只剩下 5 筆資料。

此外,SQL 命令也可以用來產生一個資料表,因此在下面這個範例中,我們直接產生一個新的資料表,然後填進去兩筆資料,然後把資料表的資料顯示在螢幕上,範例如下。

Example 4: 13-與資料庫的整合/createTable01.mcopyfile('score01.mdb', 'score02.mdb'); % 將 score01.mdb 拷貝到 score02.mdb dsn = 'dsnScore02'; % 設定資料來源名稱(指到 score02.mdb) logintimeout(5); % 設定嘗試連結資料庫的時間 conn = database(dsn, '', ''); % 連結資料庫 % 產生新資料表 friend sql = 'CREATE TABLE friend (fullName char(6), birthday date)'; exec(conn, sql); % 插入第一筆資料 sql = 'INSERT INTO friend (fullName, birthday) VALUES (''王瓊雯'', ''1983/11/03'')'; exec(conn, sql); % 插入第二筆資料 sql = 'INSERT INTO friend (fullName, birthday) VALUES (''葉佳慧'', ''1982/09/22'')'; exec(conn, sql); % 列出所有資料 cursor = exec(conn, 'select * from friend'); cursor = fetch(cursor); friend = cursor.data % 顯示更新後 friend 資料表的資料 close(cursor); % 結束 cursor 物件 close(conn); % 結束資料庫連結friend = '王瓊雯' '1983-11-03 00:00:00.0' '葉佳慧' '1982-09-22 00:00:00.0'

本節的最後一個範例,是一個比較完整的範例,其功能如下:

  1. 讀入 score02.mdb 的 score 資料表
  2. 計算每一個學生的期末總成績,等於作業平均乘以 30%,加上期中考成績(midterm 欄位)乘以 30%,再加上期末考(final 欄位)成績乘以 40%。
  3. 將每一個學生的期末成績送到資料庫的 overall 欄位。
  4. 將最後成績計算結果寫成一個網頁,以便公布給學生看。

在本範例的原始碼,我們已經加入大量註解,因此不再說明程式細節,範例如下。

Example 5: 13-與資料庫的整合/computeScore01.mcopyfile('score01.mdb', 'score02.mdb'); % 將 score01.mdb 拷貝到 score02.mdb dsn = 'dsnScore02'; % 設定資料來源名稱(指到 score02.mdb) logintimeout(5); % 設定嘗試連結資料庫的時間 conn = database(dsn, '', ''); % 連結資料庫 % 抓出所有的資料 cursor = exec(conn, 'select * from score'); % 執行 SQL 命令,並傳回 cursor 物件 cursor = fetch(cursor); % 經由 cursor 物件,抓取全部資料 score = cursor.data; % 將資料傳至 MATLAB 變數 score temp = columnnames(cursor); % 資料庫欄位名稱 eval(['fieldNames = {', temp, '}'';']); % 將欄位名稱指定到 fieldNames 變數 score = cell2struct(score, fieldNames, 2); % 將異質陣列 score 轉成結構陣列 % 對每一筆資料進行運算,並將結果存回資料庫 for i=1:length(score) homework=(score(i).homework1+score(i).homework2+score(i).homework3)/3; overallScore=homework*0.3+score(i).midterm*0.3+score(i).final*0.4; % 將資料寫入資料庫 sql = ['UPDATE score SET overall=', num2str(overallScore), ' where studentID=''', score(i).studentID, '''']; exec(conn, sql); end % 列出 score 資料表 cursor = exec(conn, 'select * from score'); cursor = fetch(cursor); newScore = cursor.data; % 更新後的資料 temp = columnnames(cursor); % 資料庫欄位名稱 eval(['fieldNames = {', temp, '}'';']); % 將欄位名稱指定到 fieldNames 變數 newScore = cell2struct(newScore, fieldNames, 2);% 將異質陣列 newScore 轉成結構陣列 close(cursor); % 結束 cursor 物件 close(conn); % 結束資料庫連結 struct2html(newScore); % 顯示結構陣列 newScore 於瀏覽器

所得到的網頁如下,其中最後一直行就是計算出來的期末成績。


MATLAB程式設計:進階篇