\documentclass[a4j]{jarticle} \pagestyle{plain} \usepackage{graphicx} \begin{document} \begin{center} {\Large データ操作} \end{center} \begin{flushright} \today \\ 峯 肇史 \end{flushright} \section{データ操作} 今回は,データベース中のデータに対する操作を行う.データベースにデータを 追加したり,データベース中のデータを変更,削除するには,DBMSが提供してい るデータベース言語を使用しなければならない.今回,実習で使用する DBMS Jasmineでは,ODQLという言語を用いる.以下のような情報をデータベースに格 納するとして JasmineでのODQLを用いたデータ操作について説明する. \begin{table}[h] 得意先(Customer)\\ \begin{tabular}{@{\vrule width 1pt~}c|c|c@{\ \vrule width 1pt}} \noalign{\hrule\hrule\hrule} 得意先コード(customerNo)&得意先名(customerName)&住所(customerAddress) \\ \hline 1 & Astore & Fukuoka \\ \hline 2 & Bstore & Tokyo \\ \hline $\vdots$ & $\vdots$ & $\vdots$ \\ \noalign{\hrule\hrule\hrule} \end{tabular}\\ 商品(Commodity)\\ \begin{tabular}{@{\vrule width 1pt~}c|c|c@{\ \vrule width 1pt}} \noalign{\hrule\hrule\hrule} 商品コード(commodityNo)&商品名(commodityName)&単価[円](unitPrice) \\ \hline 1 & Apple & 200\\ \hline 2 & Orange & 100\\ \hline $\vdots$ & $\vdots$ & $\vdots$ \\ \noalign{\hrule\hrule\hrule} \end{tabular}\\ 売り上げ(Sales)\\ \begin{tabular}{@{\vrule width 1pt~}c|c|c|c|c@{\ \vrule width 1pt}} \noalign{\hrule\hrule\hrule} 売り上げ番号&商品コード&得意先コード&数量&金額[円]\\ (salesNo)&(soldCommodityNo)&(purchaserNo)&(quantity)&(amountSold)\\ \hline 1 & 1 & 2 & 100 & 20,000\\ \hline 2 & 2 & 1 & 50 & 5,000\\ \hline $\vdots$ & $\vdots$ & $\vdots$ & $\vdots$ & $\vdots$\\ \noalign{\hrule\hrule\hrule} \end{tabular} \end{table}\\ 以下の説明では,上記の3つのクラス,Customer, Commodity, Sales が構築済で あることを前提とする. \section{リテラルとエンティティクラス} Jasmineにはリテラルとエンティティという2種類のクラス(オブジェクト)がある. データ操作の説明をする前に,これら2つについての簡単な説明を行う. \subsection{リテラルクラス} リテラルとは数字や文字のような値を指す.Jasmineでは2つの種類のリテラルが 提供されている.1つはアトミッククラスであり,これは Integerや Decimalな どの構造を持たないデータ型である.もう1つはタプルクラスであり,これは複 数のメンバから構成されるような構造を持つデータ型である.リテラルオブジェク トは,データ属性やオブジェクト変数の値として取り扱われる. 以下に Jasmineでの代表的なリテラルを示す. \begin{itemize} \item Boolean\\ TRUEか FALSEのどちらか一方をとる. \item Date\\ 月,日,年を含む日付データ. \item Integer\\ 数量を表す数値全般(整数) \item String\\ 文字列データ \item Bag$<$T$>$ \\ 型 Tのオブジェクト集合. \end{itemize} \subsection{エンティティクラス} エンティティは,リテラル以外のオブジェクトを指す.エンティティは,オブジェ クト識別子によって識別される.エンティティオブジェクトは明示的に生成され た時点(主にメソッド new()を使う)から,明示的に削除されるまで(主にメソッ ド delete()を使う)データベースに存在する.ユーザ定義クラスのオブジェクト はエンティティである. \section{データの追加} ユーザ定義クラスのオブジェクトをデータベースに追加するには,クラス手続き 属性 new()を用いる.Customerクラスのオブジェクトとして customerNoが1, customerNameが "Astore",customerAddressが "Fukuoka"であるようなオブジェ クトを追加する場合は,インタプリタで以下のように入力する. \begin{itemize} \item[$>$] Customer.new(customerNo:=1, customerName:="Astore", customerAddress:="Fukuoka"); \end{itemize} これでデータベースにオブジェクトが追加される.データベースに追加されたの を確認するためには,問い合わせを用いる.以下のようにすると Customerクラ スのすべてのオブジェクトの値を表示する. \begin{enumerate} \item $>$ Bag$<$Customer$>$ cus; \item $>$ cus = Customer from Customer; \item $>$ cus.print(); \end{enumerate} まず 1.で問い合わせの結果の Customerクラスのオブジェクト集合を格納する 変数 cusを宣言している.2.の問い合わせは,Customerクラスのすべてのオブ ジェクトを cus集合に格納する.where句がないためにすべてのオブジェクトが 格納される.3.で cusの内容を表示している.先ほど登録した Customerクラス のオブジェクトのみが登録されていれば,3.の実行結果は以下のようになる. \begin{verbatim} jasmine(mineCF) > cus.print(); Bag{ mineCF::Customer::1 { customerNo = 1, customerName = "Astore", customerAddress = "Fukuoka" } } \end{verbatim} 次に,Commodityクラスのオブジェクトを追加してみる.今回はメソッド new() の返り値(オブジェクトへの参照)を利用して,値を追加してみる. commodityNoが1,commodityNameが "Apple",unitPriceが200円であるような Commodityクラスのオブジェクトをデータベースに追加するとする. 以下のようにインタプリタで入力する. \begin{enumerate} \item $>$ Commodity com; \item $>$ com = Commodity.new(commodityNo:=1); \item $>$ com.print() \end{enumerate} 1.で新しく作成するオブジェクトのオブジェクト変数を宣言している.2.で commodityNoが1の Commodityクラスのオブジェクトを作成している.3.で作成し たオブジェクトの情報を表示している.3.を行った結果は以下のようになる. \begin{verbatim} jasmine(mineCF) > com.print(); mineCF::Commodity::1 { commodityNo = 1, commodityName = NIL, unitPrice = NIL } \end{verbatim} 上の表示結果よりわかるように,commodityNoにだけ値が入ったオブジェクトが 生成されている.Jasmineでの NILというのは,値がないことを示す.データベー スに新たに生成されたオブジェクトのデータ属性には,明示的に初期値が設定 されない限り NILが設定されるようになっている.ここで一つ注意点であるがク ラス定義をしたときに属性値に mandatoryと指定してあるところは,NILを許さ ないので,newを使用してオブジェクトを生成する場合に指定するか,もしくは クラス定義のときに default(新しく生成されたオブジェクトのデータ属性に明 示的に値が指定しなかった場合の値を指定する記述)を記述する必要がある. Commodityクラスでは commodityNoがこの例である. それでは,このオブジェクトの commodityNameと unitPriceに値を代入する.以 下のようにインタプリタに入力すると値が代入できる. \begin{enumerate} \item $>$ com.commodityName = "Apple"; \item $>$ com.unitPrice = 200; \item $>$ com.print(); \end{enumerate} 1.で オブジェクト comの commodityNameを "Apple"にしている.2.で comの unitPriceを200にしている.3.で comの情報を表示している.表示結果は以下 のようになる. \begin{verbatim} jasmine(mineCF) > com.print(); mineCF::Commodity::1 { commodityNo = 1, commodityName = "Apple", unitPrice = 200 } \end{verbatim} 以上のように,データの追加は クラス手続き属性 new()を用いることにより データベースに追加される. \section{データの変更} 以下のような Commodityクラスのオブジェクトが定義されているとする. \begin{table}[h] Commodity\\ \begin{tabular}{@{\vrule width 1pt~}c|c|c@{\ \vrule width 1pt}} \noalign{\hrule\hrule\hrule} (commodityNo)&(commodityName)&(unitPrice) \\ \hline 1 & Apple & 200\\ \hline 2 & Orange & 100\\ \noalign{\hrule\hrule\hrule} \end{tabular}\\ \end{table}\\ 上のデータの Orangeの単価(unitPrice)を150に変更することを例にとって説明 する.データを変更するには,変更すべきオブジェクトをデータベース中から見 つけ出さなければならない.そこで以下のようにしてオブジェクトを検索する. \begin{enumerate} \item $>$ Commodity com; \item $>$ com = Commodity from Commodity where Commodity.commodityName == "Orange"; \item $>$ com.print(); \end{enumerate} 1.でオブジェクト変数 comを宣言している.2.で Commodityクラスのオブジェ クトの内 commodityNameが"Apple"であるオブジェクトを検索してそのオブジェ クトへの参照を comに代入している.3.での表示結果は以下のようになる. \begin{verbatim} jasmine(mineCF) > com.print(); mineCF::Commodity::2 { commodityNo = 2, commodityName = "Orange", unitPrice = 100 } \end{verbatim} 変更すべきオブジェクトが見つかったのでそのオブジェクトのデータ属性の値を 変更する.今回は,単価を150円に変更するので,comの unitPriceを150にすれ ばよい.以下のようにする. \begin{enumerate} \item $>$ com.unitPrice = 150; \item $>$ com.print(); \end{enumerate} 1.でオブジェクト comの unitPriceを150にしている.2.の表示結果は以下の ようになる.unitPriceが 150に変更されている. \begin{verbatim} jasmine(mineCF) > com.print(); mineCF::Commodity::2 { commodityNo = 2, commodityName = "Orange", unitPrice = 150 } \end{verbatim} 以上のようにデータの変更は,まず,変更すべきオブジェクトを見つけてそ のオブジェクトに対して変更操作を行わなければならない.今回例で挙げている データ例は,データ数が少なく,かつデータベースに格納されているデータも分 かっているので,簡単な検索により見つかるが,一般的にはユーザが意図するデー タを見つけ出すのは簡単ではない.今回は,これらの検索についてこれ以上の例 は挙げないが,効率的な検索法についてはこの後の回で説明されるであろう. \section{データの削除} データの削除は,インスタンス手続き属性 delete()を用いる.以下のような Commodityクラスのオブジェクトがデータベース定義されているする. \begin{table}[h] Commodity\\ \begin{tabular}{@{\vrule width 1pt~}c|c|c@{\ \vrule width 1pt}} \noalign{\hrule\hrule\hrule} (commodityNo)&(commodityName)&(unitPrice) \\ \hline 1 & Apple & 200\\ \hline 2 & Orange & 150\\ \noalign{\hrule\hrule\hrule} \end{tabular}\\ \end{table}\\ 上の表の Appleのデータを削除することを例にして説明する. データの変更と同様に,データの削除もまず削除すべきオブジェクトをデータベー スから検索しなくてはならない.まず現在のデータを表示してみると. \begin{enumerate} \item $>$ Bag$<$Commodity$>$ comBag; \item $>$ comBag = Commodity from Commodity; \item $>$ comBag.print();\\ (表示)\vspace{-1em} \begin{verbatim} Bag{ mineCF::Commodity::1 { commodityNo = 1, commodityName = "Apple", unitPrice = 200 }, mineCF::Commodity::2 { commodityNo = 2, commodityName = "Orange", unitPrice = 150 } } \end{verbatim} \end{enumerate} それでは,commoidyNoが 1であるデータを削除する.以下のようにして削 除する. \begin{enumerate} \item $>$ Commodity com; \item $>$ com = Commodity from Commodity where Commodity.commodityNo == 1; \item $>$ com.delete(); \end{enumerate} 2.で削除すべきオブジェクトを検索して,3.で delete()を用いてオブジェク トを削除している.削除されているか確かめるには以下のようにする.確かに commodityNoが1であるデータが削除されている. \begin{enumerate} \item $>$ Bag$<$Commodity$>$ comBag; \item $>$ comBag = Commodity from Commodity; \item $>$ comBag.print();\\ (表示)\vspace{-1em} \begin{verbatim} Bag{ mineCF::Commodity::2 { commodityNo = 2, commodityName = ``Orange'', unitPrice = 150 } } \end{verbatim} \end{enumerate} これまで,あるクラスのオブジェクトを1つ削除しする例を挙げたが,あるクラ スのオブジェクトすべてを削除するには以下の2つの方法がある.Commodityクラ スの全オブジェクトを削除することを例に説明する. \begin{itemize} \item[方法1] 以下のようにする \begin{enumerate} \item $>$ Bag$<$Commodity$>$ comBag; \item $>$ Commodity com; \item $>$ comBag = Commodity form Commodity; \item $>$ scan(comBag,com)\{com.delete();\}; \end{enumerate} 1.2.は変数宣言である.3.で Commodityクラスのすべてのオ ブジェクトを comBag集合に格納している.4.の scanの文は, comBag集合の要素を1つずつ取りだし,com変数に代入し, 括弧の中の処理を行うという操作である.よってすべての comBagの要素(Commodityクラスの全オブジェクト)に対して delete()メソッドが呼び出しているので,Commodityクラスのす べてのオブジェクトが削除される. \item[方法2] 方法2では,クラス自体を削除する方法である.以下のようにす る. \begin{enumerate} \item $>$ Commodity.delete(); \end{enumerate} クラス属性メソッド delete()を呼び出して Commodityクラス自 体を削除している.この時同時に Commodityクラスのすべての オブジェクトも削除される.注意点として,この方法をとるとク ラス定義自体が削除されるので,もう一度 Commodityクラスのデー タを追加しようとすると,Commodityクラスの定義,構築を再び 行わなければならない. \end{itemize} \section{実習} 今日の実習では,データ操作を実際に行ってもらいます.以下の手順で実習を 行って下さい. \begin{enumerate} \item インタプリタを起動. \item クラスファミリの修飾をする必要がないようにデフォルトのクラスファ ミリを自分のクラスファミリとする.\\ $>$ defaultCF accountCF; \item 「問い合わせ」の回の輪講で定義したオブジェクトのデータが残って いる人は,データの削除のところで説明した,クラスの全オブジェクト を削除する方法を用いてデータを削除. \item 1ページ目に書いてある3つの表のデータを,自分のクラスファミリのク ラスオブジェクトとして追加. \item Commodityクラスの commodityNameが "Apple"であるオブジェクトの unitPriceを150に変更. \item Commodityクラスの commodityNameが "Orange"であるオブジェクトを削 除. \end{enumerate} \end{document}