2012年3月3日土曜日

やり直し JAVAサーブレット(基礎からのサーブレット/JSP [改訂版] )その4

(p86) はじめてのJSP

JSPは コンパイルが不要で、web . xml への登録も不要。
作成した . JSP ファイルはコンテキスト名直下(entryフォルダ内)に置く。
tomcat は起動している必要がある。
htmlファイルと同じような特徴です。
JSPのコードもHTMLの中に埋め込むような格好になっている。

コンテキストとは? コンテキスト名とは?(復習) 
http  :  //    localhost   :   8080   /    entry   /   hello.txt
プロトコル      サーバ名     ポート番号   コンテキスト名 ファイルのパス

JSPの式(Expression)とは、
” <%= ”、” %>” で囲む。 


(p88) JSPはサーブレット

この章の始め(p86)に、『JSPはサーブレットと違って…』という記述があったの
だけれど、JSPはサーブレットらしい。クライアントからリクエストが発生した際
コンテナは、

①” . jsp ” ファイルを ”. java”ファイルに変換し、
②その” . java ” ファイルがコンパイルされ、
③”. class”ファイルが生成され、
④”サーブレットのインスタンスが生成される。
という4段階の過程を踏むらしい。
よって、最初にアクセスがあった場合のみ、変換やコンパイルで時間が長くかかるらしい。

これまで、サーブレット(”○○servlet . java” ) を記述した場合、
意識して WEB-INF フォルダ内の src フォルダ を探し、そこに保存してから、
コンパイルするという(class フォルダへ class ファイルの保存は自動的だが)。
少々面倒なことを意識し、  さらには、web . xml に登録しなければならなかったが、
JSP はそれらが不要と言うことですね。
ちなみにコンテナが①~④を実行してくれますが、
” . java ” ファイルや、”. class ” ファイルは、

使用中の tomca tフォルダ > work フォルダ >Catalina フォルダ >localhost フォ
ルダ >entry フォルダ >org フォルダ >apache フォルダ >jsp フォルダ 内に保存
されています。


(p89) JSPを変更した場合

サーブレットを変更した場合は tomcat を再起動(Webアプリケーションをリロード)
する必要がありましたが、JSPの場合は不必要。 なぜ?
それは、JSPにアクセスした時に、再び ①JSPの変換、②javaコードのコンパイル、
③classファイルの生成、④サーブレットインスタンスの生成が行われるから。


(p90) スクリプトレットを使ってみよう

スクリプトレットとは、見た感じ ”JSPの式” に似ている。
<%= ○○○ %>  …  JSPの式
<%   ○○○  %>  …  スクリプトレット

スクリプトレットにはjavaのコードを記述できる。


(p91)  出力用の変数out

out はオブジェクト? 変数? 混乱してきた。
ググッたら、 わかりやすいブログを見つけたので勉強させてもらいました。
稲員勇輝さんありがとうございました。

コンテナは、
" . jsp ファイル” をサーブレットに変換する際に、予めよく使うであろう変数
( out を含む) を宣言してくれているらしい。 よって、JSPコード内でいちいち
out を宣言しなくてもすぐ使えるようになっている。
これも JSP が楽チンであると言う要素ですね。

この out 変数 には、
JspWriter . class 型のインスタンス(インスタンスのアドレス)が入るようになっている。
JspWriter . class 型を詳しく調べたわけではありませんが、どうやらブラウザへの
レスポンスインスタンス(response)に出力する機能を持っているようですね。 

” out ” はオブジェクトと短絡的にイメージしていたが、厳密には
” out ” は インスタンスが存在するメモリー上のアドレスが入るわけで、
変数ですね。

たぶん小生の認識で間違いないと思うのですが、いろいろ確認してみてください。


(p94) JSPのコメント

<%-- JSP Comment --%>  これがJSPのコメント
<!-- JSP Comment -->    これはHTMLのコメント

JSPをサーブレット(javaコード)に変換すると、 javaコードの中にHTMLを生成するが、

そのHTMLの中に <%-- JSP Comment --%>は存在しない。
 
<!-- JSP Comment --> はブラウザでは表示されないが、HTML には存在する。

(p95)コンテンツタイプの指定

JSPでコンテンツタイプを指定するには、” page ディレクティブ ” を使用する。
<%@page contentType="text/html ;  charset=Windows-31J" %>

ディレクティブとは?
<%@ ○○○ %>で記述するタグを言う。
これに、page が付く ( <%page ○○○ %> )と、
ページディレクティブとなる。


(p97) import宣言

外部クラスをインポートする場合は、page ディレクティブの import 属性を使う。
ここでは、現在時刻を表示する訳だが、”java.util.Date”クラスが必要となり、
JSPコードの最初の段階で、
<%@page import= "java.util.Date" %> でDateクラスをインポートしている。

このおかげで、<%= new Date() %> の記述で、日付が求められる。

このインポートの記述は、複数行に分けて、複数インポートすることもできる。
また、ワイルドカード(*)により1行で複数インポートすることもできる。

javax.servlet、javax.servlet.http、javax.servlet.jsp パッケージについては、
デフォルトでインポートされるので記述はいらない。


(p102) コンテキストパスを理解する

”コンテキスト” とは、個々のWebアプリケーション(これまでの内容では ”entry”)

|←      リソースのURL                                  →| 
|←      WebアプリケーションのURL               →|
|←      サーバのURL          →|

 http : // localhost : 8080  /   entry     /   hello.txt
                ↑        ↑         ↑         ↑     ↑
             サーバ名  ポート番号  コンテキスト名     ファイルのパス
                                   
※コンテキストルート         コンテキストパス = コンテキストルートまでの道のり


コンテキストルートには index.html ファイルなどが配備してありますね。

よって、context.jspでは、
サーバのルート("/" = http://localhost:8080)では、
TOMCATのページが表示され、
リクエストインスタンスの getContextPath() メソッドが返す文字列(”/entry” ※)
では、index . html が表示される。
※ 絶対URLに直すと ”http://localhost:8080/entry” と言うことだが、
少々もやもやしている。 


(p105) JSPからサーブレットを呼び出す

テキスト通りコードを入力するも、期待通りの結果は得られない。
”サーバルート”からのパス” は ”servlet”を削除(小生のtomcat7では
invoker を利用できない)することで、表示されるようになったが、
”カレントからのパス” は どのように修正してもエラーとなる。 
そもそも、ここで言う ”カレント(. jspファイルから?)からの” の意味が良く
わからない。理解していないのか?!

いろいろ試した結果、


<p><a href="../../../entry/HelloServlet">HelloServlet</a>
(カレントからのパス)

と変更することで期待通りの結果が表示された。

JSPコードからjavaコードに変換されて、コンパイルで生成されたクラスファイルは

 tomcat7\work\Catalina\localhost\entry\org\apache\jsp 

ここに保存されているということですかね。

まだ、知識が浅いようだ。

取り敢えず先へ進むこととする。



情報処理 再チャレンジ ブログ ホーム へ




2012年3月2日金曜日

やり直し JAVAサーブレット(基礎からのサーブレット/JSP [改訂版] )その3

(p56) 練習問題

現在時刻を返してくるサーブレットを作成させる問題。
なにやら ”java . util . Date()” なるクラスを使うようだ。
いきなり ”PrintWriter out = response . getWriter()” など
を使えば実現できるとの ヒント が出てくるが、
PrintWriter とか もやもやした状態で なんだか気持ちが悪い。
ここまでいつもそんな心境でホントに技術を習得できるのか心配だった。

とりあえず、
①エディターに HelloServlet を読み込み、それを編集後、
名前をつけて classes フォルダ 内 foo フォルダ に保存。
②ディレクトリ WEB-INF へ移動して、 >compile foo/NowServlet . java
エラーが1件( ”;”のつけ忘れ)でたが、難なく
classes フォルダ 内 foo フォルダ に NowServlet . class が生成された。
③web.xml にコードを追加し、
④( Tomcat を再起動することなく )ブラウザに  ~/NowServlet と入力
⑤無事、ブラウザに現在時刻が表示された。

今回の練習問題では、
コンパイルの際に1件のエラーは出たものの、エラーメッセージが理解できた。
また、 ほとんど直感で回答できた。
もやもやしっぱなしではあったが、それなりに実力はついているようで、
ちょっぴり安心した。


(p59) HTMLを出力するサーブレット

ブラウザに ”こんにちは” と表示するだけのサーブレット。
ポイントは、日本語を表示させる為の約束事を確認すること。
doGet()メソッド内、最初の段階で response インスタンスが持つ
setContentType()メソッドで response インスタンス自身に
情報をセットしている。 

詳細はまだもやもやしているが、先へ進むことにしよう。

※一般的な Web アプリケーションでは ” text/html ” とセットするのとの事。
※tomcatでは デフォルト文字エンコーディングが ISO-8859-1 に設定されて
いる為 setContentType()で 日本語の文字円コーディングを設定しなけ
ればブラウザに日本語が表示されない。
※setContentType()で指定した文字円コーディングは PrintWriter からの
出力に利用される。
※PrintWriter オブジェクトを取得する前に、setContentType() を実行しなけ
ればならない。 


(p65) プレーンテキストを表示するサーブレット

”(text/plain; charset=Windows-31J”) と
”(text/html; charset="indows-31J”)  の違いを確認する。

html は<br>が改行を意味するので、ここでは文字列が連続されて表示する。


(p69) 練習問題

P51で出てきた OracleServlet とほぼ同じ技術。違いは日本語を出力するかどうか。
※ setContentType() メソッドを使用する。



(p73) web.xmlの基本

XML(eXtensible Markup Language) とは、文書やデータの構造をあらわす為の
マークアップ言語。 これは HTML のようなタグで 文字を埋め込んでいく方式の
言語を言うらしい。また、eXtesible(拡張)が示すとおりユーザーが自由にタグを
拡張することができるらしい。タグを拡張とは? ???

教訓1 もやもやしてても取り敢えず先へ進む!


XMLの宣言
先頭の1行は <? ~ ?> で括る。これを宣言と言い、省略できるが書いたほうが良い。
ヴァージョンやエンコーディング、スタンドアロン文書(?)かどうかを記述できる。



ルート要素
単一のルート要素(?) さっぱりわからない。


要素と属性
XMLの基本単位は要素。
”文字列” の”文字列”は テキスト要素となる。


要素に付加する付属的な情報を属性と言う。 属性はタグの中に
< ○○ key=value > の形式で記述する。


大文字・小文字
区別される。


開始タグと閉じタグ
HTMLと同じ。<book> ~  </book> とする。
ちなみにテキストに出てる <book/> は誤植であろう。


XMLのコメント
コメントを記述したいときは ”<!--” 、 ”-->” で括る。
< ! -- コメント --> とする。

< ! --
コメント
コメント
コメント
--> 

と言う書き方でも良い。


スキーマ
XMLは複数のプログラムの間でやり取りされるデータである為、
文法チェックを行う仕組みを取り入れている。※省略可
XMLの構造を定義したものをスキーマと言い、これを用いて
文法チェックを行う。
最も基本的なスキーマをDTD(Document Type Definition) と言い、
さらに複雑な定義を行うため、XMLスキーマ、RELAX NG などが利用
できるらしい。API2.4以降XMLスキーマが利用されているらしい。

スキーマの定義(dtd)は下記のようなもの。
<!ELEMENT books (book *)>
(!ELEMENT book (title)>
<!ATTLIST book
isbn CDATA #REQUIRED
>

整形式(Well-Formed)と妥当(Valid)
XMLの基本的な文法(開始タグに対する閉じタグがある)を満たしたXMLは
”整形式のXML” と言い、スキーマが用意されている場合でそのスキーマ(文法)
を満たしているXMLを ”妥当なXML” という。

web . xml では、先頭に宣言があり、次にXMLスキーマを記述し、
その後に<servlet>、<servlet-name>、<servlet-mapping>、<url-pattern>などが
続く。
ここまで何度となく記述していた web.xml は宣言、XMLスキーマなどを省略していた。

<web-app> ~ </web-app> の中に記述していましたね。

HTMLでも、しっかり宣言を入れておいたほうが良いとの話を耳にした事があるが、
※省略可  XMLが少し見えてきた感じがする!!


(p82) invokerサーブレットの設定
今回小生が使用している Tomcat は tomcat7 である。
conf フォルダの中に web . xml はあるのだが、” invoker ” の記述がない。
ググッてみたら、tomcat7 からは invoker サーブレットはなくなっているらしい。
人類みんなごくつぶし さんのブログに詳しく載ってました。

ここの記述は少々複雑でいまいち整理できていないが、
invoker と言う名前で servlet-name を定義して、
servlet-class としては、 何かの サーブレット . class
定義 (コンテナ内にあるの?) し、
pattern/servlet/* として、
ブラウザからフルパスでクラスを指定できるようにしている。

この結果、いちいち作成したサーブレットを web . xml に登録しなくても
良いようになる。

基本、サーブレットは web . xml に登録しないと実行できない。
invoker サーブレットは Tomcat 独自の機能。
invoker サーブレットは セキュリティ上の問題がある。




情報処理 再チャレンジ ブログ ホーム へ

2012年3月1日木曜日

やり直し JAVAサーブレット(基礎からのサーブレット/JSP [改訂版] )その2

(p46) オートリロードの設定
サーブレットの Javaコード( . javaファイル )は
コンテナ上の src フォルダに格納する。そのJavaコードを
コンパイルし生成した . classファイルは WEB-INF フォルダに
配備する。これは基本事項ですね。

これまでの過程で、src フォルダに置いた . java ファイル は
compile . bat  で コンパイルすると、自動的に WEB-INF フォルダ
. class ファイルが生成される。

先ほどの HelloServlet.java ファイルを一部訂正し、再コンパイルすると、
すでに存在している Hello.Servlet.class の内容は更新されている。

結果を確認すべく、
ブラウザ で サーブレット(.class)ファイルが更新されたか確認すべく、
更新ボタンを押すも、画面はまったく変わらない。

コンパイルにより コンテナ内の WEB-INF フォルダに.class ファイルは配備されて

いるはずだが、ブラウザ(クライアント)にはなぜ反映されないのか?
メカニズムははっきり見えないが、コンテナ(Tomcat)を再起動
しなければならないらしい。クライアントは WEB-INF を見に行くと思っていたが、
もう少し複雑なのですね。

前置きが長くなりましたが、ここでは  Tomcat を再起動せずとも、再コンパイルのみで
済ませる技術(Tomcat独自の仕組み)が紹介されている。

コンテキストルート内(entryフォルダ内)に META-INF フォルダを作り、その中に
context.xml を作成する。
内容は <Context reloadable="true"/> だけでよい。
これをコンテナに置きっぱなしにしていると、運用時にパフォーマンスが落ちる。
手動のリロード なるものがあるらしい。
eclipse では、再起動ボタンを押せばすむので、オートリロードは、さほど
重要ではないと思った。


(p48) パッケージ付のサーブレット
パッケージについてはその概念の必要性がはっきりしないが、開発上有効な
ものなのだろう。p49で web.xml に追加しているが、コンテナが持つ サーブレットの
数だけ、<servlet-name>、<servlet-class>、<servlet-pattern>の定義が必要である
ことが見て取れる。
p50では src フォルダ内 に fooフォルダを作成し、その中にBarServlet . java を
作成して、コンパイルするコマンドが乗っている。
> compile foo/BarServlet.java
であるが、p44 で説明があった、”%1にはバッチファイルに渡される引数~” の
意味が理解できた。改めて javac コマンドを ググッてみたが、奥が深いね。



(p54) Oracle . java も自動的にコンパイルされる。
小生は、Oracle . java と OracleServlet . java をそれぞれコンパイルしたが、
ここでは OracleServlet . java のみコンパイルすれば自動的にOracle . java も
コンパイルしてくれる。メカニズムは後から理解できるだろうと思い、深く追求せずに
次に進む事とする。





情報処理 再チャレンジ ブログ ホーム へ

2012年2月29日水曜日

Windows 7(vista) の機能 拡張子を表示させる


①任意のフォルダーを開く

②左上にある 整理 をクリック




③フォルダーオプションと検索のオプションをクリック


④フォルダーオプションダイアログボックスが表示される


⑤表示タブをクリック


⑥詳細設定下部の”登録されている拡張子は表示しない”のチェックをはずす





情報処理 再チャレンジ ブログ ホーム へ

2012年2月28日火曜日

やり直し Java Servlet ( 基礎からのサーブレット/JSP[改訂版] )その1

(p22) Webアプリケーションのディレクトリ構造
JSP、HTML、画像、TEXTファイルなどはコンテキスト名(entry)の直下に
配置するとの事で、

①”hello.txt” をテキストどおりに作成して配置する。
②tomcat7/bi/Tomcat7w を右クリックで管理者として実行(A)...
③ブラウザのアドレスに ”http://localhost:8080/entry/hello.txt と入力

するも期待通りに表示されない。
”わかりやすい!” と薦められて買ったテキストの、出だしの一番簡単な
箇所で つまづいていては、”サーブレットを諦めろと” 言われているような
もので、一気にテンションが下がってしまった。

これって、よくあるミスなのではないかと思うが、
 webappsフォルダ内に右クリックで entryフォルダを作成し、
entry フォルダ内でまた右クリックして、”hello.txt” を作成していたのである。
その後にメモ帳で hello.txt を編集して上書き保存し、”hello.txt” が完成
したものと思い込んでいた。
このやり方では、”hello.txt.txt” が作成されてしまうのである。

ファイルの拡張子を最初から表示させておけば陥らないミスであった。


(p37) JAVAファイルの作成
ここでサーブレットコードが出ていて、問題なく動作はしたが、
doGet()メソッド のメカニズムがわからず、先へ進めなくなった。
細かい概念はもう少し慣れてきてからとの考えだったのでしょうが、
サーブレットコンテナについてもう少し情報が欲しかった。
doGet()メソッドは2つの引数を持っています。
1つ目の request インスタンスは、なんとなく クライアントからの
リクエストを元に、この第1引数に収まるのはイメージできるが、
2つ目の response インスタンスの response は、
『サーブレットが処理をした後にクライアントに返すもの』 という
イメージから、
・メソッドは引数にインスタンスが入らないと起動しない。
・第2引数はメソッドが処理をした後に出来上がる。
これまでの学習から、どちらも正しいと思うが、そうだとしたら
矛盾が生じる。

を解消する情報が見つけられなくて、実は3ヶ月くらい学習が停止した。

乱暴なイメージだが、
①クライアント → httpサーバ → コンテナ → doGet()メソッド等


②doGet()メソッド等 → コンテナ → httpサーバ → クライアント

で、データが流れるが、①でコンテナが、リクエスト情報を元に doGet()に
渡す2つのインスタンスを生成し doGet()に渡している。
この際、response インスタンスに関しては、せいぜいクライアントが指定して
いるサーブレットが存在するか?しないか?で、200 とか 404 とか の情報を
持つ、その他は空のインスタンスが生成され doGet()メソッドに渡す。



(p44) コンパイル用バッチファイルの作成
JAVAの開発は eclipse を基本とするため、あまり重要ではないとも思ったが、
基本を確実にしたくてテキスト通り compaile.bat を作成する事にした。

@set CLASSPATH=C:\servletbook\apache-tomcat\common\lib\servlet-api.jar
javac -sourcepath src -d classes src/%1

上記2行をバッチファイルとして WEB-INF フォルダーに配置することで、

javac コマンド発行時に 楽してコンパイルできるというもの、

テキストを読んでいて、そう難しくはない記述なのだったが、実行結果が期待通りにならない。
だいぶ悩んだ挙句、”CLASSPATH"を小文字にしていた事が良くなかったようだ。

表記の通り大文字で書き換えたら解決した。


情報処理 再チャレンジ ブログ ホーム へ

2012年2月27日月曜日

MySQL ぜひ覚えたい 関数 式 句 などの覚書(p181~)

『基礎からのMySQL』 西沢夢路著 (ソフトバンククリエイティブ) 
から得たぜひ覚えたい個所を列挙した。 Part3




(p182) 複数の抽出結果を合わせて表示する。
 ①select * from tb1 ; ②select * from tb2 ; の結果を
一度に表示させることを union で実現している。

select * from tb1 union seleect * from tb2 ;


これを見やすくする為、


(select * from tb1) union (select * from tb2) ;


なんて事もできる。



(p184) 3つ以上のテーブルから「union」で集める。

       (select * from tb where bang = 'A102')
union
       (select * from tb where bang = 'A103'
union   
       (select * from tb where bang = 'A104'
union
       (select * from tb where bang = 'A107') ;


と発行する事で、bang で抽出された4つの結果をまとめて
表示させる事ができる。


グループ化して表示させているように見える。


また、


select * from tb where bang not in ('A101') ;


というSQL文も紹介されている。 これは

テーブル内の bang が A101 以外を表示するもの。



select * from tb where in ('A101','A103',104'A','A107') ;

は、見慣れない SQL文 で戸惑ったが、

()内にあるものをグループとみなして、

そのグループに属するレコードの中から抽出するもの

ですね。





(p185) 条件を付けて複数の抽出結果を合わせて表示する。
 
 ① tb から uria が200以上のレコード持つ bang を抽出
 ② tb1 から tosi が35以上のレコード持つ bang を抽出


(select bang from tb where uria >= 200)
union
(select bang from tb1 where tosi >= 35) ;



結果は A101 , A102 , A105 の3件が抽出される。


2つのSQL文の結果を union はつなげて表示させている。


注意したいのが、

①の抽出結果は、A101 , A102 の2件であり、
②の抽出結果は、A101 , A105 の2件である。
合計 4件 が表示されるかと思いきや、
自動的に重複表示を制限しているのである。



重複表示を許す場合(純粋な OR 抽出?)は、

(select bang from tb where uria >= 200)
union all
(select bang from tb1 where tosi >= 35) ;



と、union に続けて all とすれば良い。



大量のデータを処理する場合は、union(重複を省く)では、

処理時間が長くなり、 union all(重複を許す)とすると、


処理時間が短くなる。らしい。




(p188) 複数のテーブルを結合して表示する(内部結合)。

 いよいよリレーショナルデータベース(以降RDB)らしい
内容になってきます。RDB = 複数テーブルを関連づける
という概念ですが、直前の union のところでも、2つのテーブル
(tb と tb1)を使って結果を表示していました。
ちょっと立ち止まり概念を整理したのですが、
union のところでは、2つのテーブルからの抽出結果を
ただ単に連続表示していただけでした。

内部結合 join 句 (※ INNER を指定すると、内部結合を「明示的」に指定できる。)は、
複数テーブルが共通に持つフィールドの値でテーブルを関連
づけ、実在するテーブル(tb , tb1)が持つ情報を、非実在の
テーブル(仮想テーブル)を作成し、それを表示している。

テキストでは、
select * 
    from tb 
join tb1
    on tb.bang = tb1.bang ;  

これは、 テーブル tb の bang と テーブル tb1 の bang が
同一であった場合に、それぞれのテーブルからレコードを
抽出し、全フィールドを結合して一件のレコードとして表示
するというものですね。
 
うまい表現ではないような気もしますが、
1レコード6フィールドの ハードディスクには実在しない
テーブル(仮想テーブル)を画面上に表示します。


内部結合 という事は、 外部結合 もある訳で、その違いを
把握しておきたいところですが、

テーブル tb には bang が A101、A102、A103、A104、A107 
の5種類、計10件のレコードが存在していて、
テーブル tb1 には bang が A101、A102、A103、A104、A105 
の5種類、計5件のレコードが存在している。


先の内部結合のSQL文では、9件のレコードが表示されたが、
bang が A107(tbだけにある) と A105(tb1だけにある) の
レコードは表示されなかった。 内部結合は、片方にしかない
情報は排除し、仮想テーブルには含めないのです。

それに対して、外部結合は片方にしかない情報も
仮想テーブルに 加えます。


    左のテーブル          右のテーブル
  bang   uria  tuki     bang   nama   tosi
  A103  101  4  |   A101   佐藤    40
  A102   54 54  |   A102   高橋    28
  A104  181  4  |   A103   中川    20
  A101  184  4  |   A104   渡辺    23
  A103   17  5  |   A105   西沢    35
  A101  300  5  |
  A102  205  6  |
  A104   93  5  |
  A103   12  6  |
  A107   87  6  |


左外部結合(left join) と 右外部結合(right join)。
inner join の inner を、left または right  に置き換えると、
左(右)外部結合の結果が得られます。

左外部結合とは、左のテーブル(tb)に 右(tb1)にはない
フィールド が存在する場合、そのデータも仮想テーブルに
加えてしまいます。違う言い方をすると、
左外部結合の結果は左テーブルのレコード総てを
仮想テーブルに加えて、右テーブルからは特定のキーに
よって一致するレコードを抽出し仮想テーブルに加える。
という事ですね。


(p194) using を使って on ~ の部分を見やすくする。
 テーブルを関係づけるために、
on tb.bang = tb1.bang (bang)というフィールドの内容が
同一かを判定させる。ここでは たまたま 2つのテーブルで
bang というフィールド名でしたが、
tb では、bang、 tb1 では bangou というフィールド名で
A101 やら A107 というデータを保持させていた場合、
「 on tb.bang = tb1.bangou 」 とすれば、テーブルどうしを
結合させられる。
using 句は、仮に2つのテーブルで、A101 やら A107 の
データを同じフィールド名で管理している場合、
join tb1 on tb.bang = tb1.bang を 
join tb1 using (bang) と簡単に記述できるというもの。




(p195)  
結合したテーブルから「where」で設定した条件で抽出する。
 結合した仮想テーブルから where 条件でレコードを抽出
する際は where句の条件では フィールド名だけではダメ。
必ずテーブル名を指定して MySQL に示してやる必要が
ある。

select tb . bang , tb1 . nama , tb . uria 
         from tb
join tb1
         using(bang)
where tb . uria >= 100




(p 197) たくさんのテーブルのデータを使って抽出する。
 テーブルの結合は2つ以上可能で仮に3つのテーブルを
結合する場合は、

select
       tb.bang,tb.uria,tb1.nama,tb3.ken
from
       tb
join
       tb1
using(bang)
join
       tb3
using(bang)
;
とする。




(p200) 
複数のテーブルの総てのレコードを表示する(外部結合)。
 内部結合(p188)後半の記述を参照。




MySQL ぜひ覚えたい 関数 式 句 などの覚書(Part1)へ

MySQL ぜひ覚えたい 関数 式 句 などの覚書(Part4)へ






情報処理再チャレンジブログ ホーム

2012年2月26日日曜日

MySQL ぜひ覚えたい 関数 式 句 などの覚書(p164~)

『基礎からのMySQL』 西沢夢路著 (ソフトバンククリエイティブ) 
から得たぜひ覚えたい個所を列挙した。 Part2




(p164) UPDATEコマンド
 テーブルの特定のカラムを指定した値に変更する。書式は、
update テーブル名 set カラム名 = 設定する値 ; で、
一瞬にしてカラムの値が変更される。通常 
where句 と共に使用される為、全レコードの特定カラムを
一気に変更することは少ないらしい。

テキストでは、 tb という既存のテーブルに、
①新しく 「bikou」 というカラムを追加して、
そのカラムに②「特記なし」という文字列を設定している。

① alter table tb add bikou varchar(100) ;
② update tb set bikou = '特記なし' ;





(p167) 条件に一致したレコードだけを修正
 書式は、
update テーブル名 set カラム名 = 設定する値 where 条件 ;
テキストでは、 tb テーブルの uria が 100 以上のレコードの
bikou に 「優秀」 という文字列を設定している。
update tb set bikou = '優秀' whrer uria >= 100 ;



(p169) 売上下位3件の bikou フィールドに 「ガンバレ!」を設定
 uria フィールドの値で、下位3件を抽出はどうする?
① uria フィールドを 「order by」で並べ替える。
  ここでは小さい値から大きい値へ並べ替えられる(内部的に)。
② limit3 で最初の3件を抽出する(下位3件)。

 update tb set bikou = 'ガンバレ!' order by uria limit 3 ;



小生の感覚では、where句 で抽出したくなり、当該コマンドは
しっくりこない。経験を積むことで自然と理解が深まり、違和感が
解消されることを期待し先に進む事とする。


(p171) 特定のフィールドを削除する。
 テキストでは、tb テーブルの bikou フィールドを削除している。
書式は、 alter table テーブル名 drop フィールド名 ;
alter table tb drop bikou ; というコマンドを発行している。



(p171) 条件に一致したレコードをコピーする。
 ①条件に一致したレコードを抽出し、新しくテーブルを作成。
   create table tb_A101 select * from tb 
        where bang like 'A101' ;

 ②条件に一致したレコードを抽出し、既存のテーブルに追加。 
     insert into 既存テーブル名 select * from tb 
                 where bang like 'A101' ;

(p173) レコードを順番に並べてコピーする。
 テキストでは、
① tb テーブルのレコードを uria フィールドの値を基準にして
   降順に並べ替え(order by uria desc)、
②上位4件を抽出している(limit 4)。
③さらに、最上位のレコードを省いて、その代わりに
  uria フィールドが 5番目に大きい レコードを上位4件に
  加えている(offset 1 … 最上位レコードを1つ下のレコード
  とする)。
④手順③までで抽出したレコードを新しいテーブルとして作成。
  create table tb_2to5 select * from tb
                    order by uria desc limit 4 offset 1 ;



(p175) 全レコードを削除する(テーブルは残す)。
 「削除」 といえば DELETE! と閃いた次の瞬間、DROP でも
良いのかなぁ? と 少し ”もやもや” している事に気付く。


テキストにも書いてある通り、DROPテーブルを削除し、
DELETEレコード全部を消去しても、空のテーブルは残る。

※updateコマンドよりも慎重に発行する事が求められる。

さて、特定のレコードを削除する場合の書式は、
delete from テーブル名 where 条件 ; で、
テキストでは、
delete from tb1k where tosi < 30 ; を発行している。
(tb1 と全く同じ tb1k というテーブルをあらかじめ作成しておく)

結果は、tb1kテーブル にレコードは 2件が残る。
(tosi が 30 未満のレコードは削除される)

(p177) テーブルをソートしてから、特定のレコードを削除する。
 テキストでは、テーブル tb 同一内容のテーブル tb_copy が存在している事を前提にしているので、あらかじめ作成しておく。

以下の手順①,②で作成される 【仮想テーブル】 の内容を、
【実テーブル】である tb_copy から削除する。


① テーブル tb_copy の uria フィールドの値を基準に降順に
   ソートする。
② limit 4 で 上位4件のレコードを抽出する。


結果は、6件のレコードだけが tb_copy に残る。


(p179) 期間でレコードを抽出する。
 ここでは、【 now() - interval 5 year 】で、
現在より5年前を表している。 

now() 関数を使わずに interval の使い方を試すことにした。
 条件を 【 '2012' - interval 5 year】 としたら、エラーにはならず、Mysql は 「 Empty ○○○ 」 と返してくる。文法は正しいものと
思い、いろいろ試すも思うような結果が得られない。

結局 '2012'  を 'current_timestamp' とする事で、期待通りの
結果が得られた。

それから、「~ interval 5 years 」 とするとこれはエラーに
なってしまう。英語に精通している小生としては(うそ)。
違和感を覚える。




MySQL ぜひ覚えたい 関数 式 句 などの覚書(Part1)へ

MySQL ぜひ覚えたい 関数 式 句 などの覚書(Part3)へ




情報処理再チャレンジブログ ホーム