1.選択1.1 条件2.データの変更1.2.1 結合1.3 テーブル演算子
1.2.2 別名定義
1.2.3 外部結合1.4.1 条件としての副問合せ1.5 関数
1.4.2 from句での副問合せ1.5.1 関数の種類1.6 結果のソート
1.5.2 group by句
1.5.3 グループ関数を条件に使用する(having句)
1.5.4 条件判断(DECODE)2.1 挿入(insert)3.sql*plus3.1 sql*plusへのログイン3.2.1 バッファとファイルとのI/O3.3 リストの作成
3.2.2 バッファに関するコマンド
3.2.2 バッファに関するコマンド
3.2.3 エディット機能3.3.1 結果のファイル出力の開始と終了3.4 インターフェイスの作成
3.3.2 実行結果の整形例
テーブル(表)とは・・・
行とカラム(項目)から構成される テーブル名を持つ
カラム(項目)とは・・・
情報の最小単位 項目名をもつ 型(文字型、数値型、日付型、バイナリ型)を持つ
行(レコード)とは・・・
テーブルの中に入る、同じ構造をもつ情報 一意に指定が可能
SQLとは・・・
4GL(第4世代言語)と呼ばれる、RDB上の言語 データ操作(DML)を行う データ定義(DDL)を行う
DMLとは・・・
テーブルの関係演算を行う(select) 行の値に関する操作を行う(insert、delete、updateなど)
(基本形)
select カラムのリスト
from テーブル(のリスト)
where 条件;
selectの後には、抜き出したい項目の項目名を並べる。
(カラムのリストは'*'でも可、その場合テーブルの全項目が指定される)
from句には、その項目が入っているテーブル名を指定する。
where句には、選択したい行の条件を指定する。
(where以降の省略可、省略時はテーブルに含まれる全ての行が選択される)
(例)select IPアドレス,
利用者名
from PC管理マスター
where 利用者名 = '大川';
*参考*
結果の表示の見出しには、通常、項目名が自動的につけられるが、変更することも可能である。これは特に、関数を使った項目の表示の場合に指定すると有効である。
(例)select IPアドレス アドレス,
利用者名 氏名
from PC管理マスター
where 利用者名 = '大川';
| = | :等しい |
| > | :大きい |
| < | :小さい |
| >= | :大きいか、等しい |
| <= | :小さいか、等しい |
| != | :等しくない |
| <> | :等しくない |
| % | :任意の長さ(長さ0を含む)の文字列 |
| _ | :任意の1文字 |
*注意*
SQL文を読み取るときに、後述の論理演算子としてのandと混同しないように
条件は論理演算子によって組み合わせることができる。
*参考*
条件1 and 条件2 条件1を満たし、かつ、条件2も満たす 条件1 or 条件2 条件1を満たすか、または、条件2も満たす not 条件1 条件1を満たさない
(例)select 利用者名,WEB利用履歴.IPアドレス,URL,アクセス日時
from PC管理マスター ,WEB利用履歴
where WEB利用履歴.IPアドレス = PC管理マスター.IPアドレス and
利用開始日 <= アクセス日時;
項目のリストで、IPアドレスにだけ「WEB利用履歴.」とついているのは、項目名の修飾といい、2つのテーブルの両方に同じ項目名があり、どちらテーブルの項目を指定しているのかを示すためである。
3つ以上のテーブルを結合することも可能である。
*注意*
結合の条件は正しく指定しないと誤った結果(積)が得られるが、気づきにくいことが多い・・・
whereを指定しないと、直積が得られる。たとえば、PC管理マスターが100件、WEB利用履歴が400件あった場合、結果は40000件になる。
(例)select PC.利用者名,
WEB.IPアドレス,
WEB.URL,
WEB.アクセス日時
from PC管理マスター PC,
WEB利用履歴 WEB
where PC.IPアドレス = WEB.IPアドレス;
PC.利用開始日 <= WEB.アクセス日時;
テーブル名の後ろに空白をあけて記述したもの(PCとWEB)が、テーブルの別名定義である。
別名定義を利用して、同じテーブル同士を結合させることもできる。
(例)select PC1.利用者名,PC1.PC名,PC2.PC名
from PC管理マスター PC1,PC管理マスター PC2
where PC1.利用者名 = PC2.利用者名 and
PC1.PC名 < PC2.PC名;
*注意*
この例では、PCを2台(以上)持っている人の名前とそれらのPC名の一覧が表示される。
3台以上持っている人がいる場合、悲しい結果になってしまうのだが・・・
(1台しか持たない人は表示されない。2台もっている人のレコードは1件だけだが、
3台持っている人は、3件になってしまい得たい結果とは異なってしまう。
ちなみに4台持っていると、6件にもなってしまう!!)
(例)select PC.利用者名,
WEB.IPアドレス,
WEB.URL,
WEB.アクセス日時
from PC管理マスター PC,WEB利用履歴 WEB
where PC.IPアドレス(+) = WEB.IPアドレス and
( PC.利用開始日 is null or
PC.利用開始日 <= WEB.アクセス日時 );
この結果は、WEB利用履歴にあるレコードは全て表示し、PC管理マスターに登録があるIPアドレスならばその利用者名を表示、登録がなければnull値になっている。
unionとunion allとの違いは、unionの場合は、2つの結果を足し合わせた集合から、重複行は一つの行にまとめている点である。
union :2つの結果の和集合をとる union all :2つの結果を足し合わせる minus :前方の結果から後方の結果を引いた集合をとる intersect :両方の結果に含まれる集合をとる
(例)select PC.利用者名,
WEB.IPアドレス,
WEB.URL,
WEB.アクセス日時
from PC管理マスター PC,WEB利用履歴 WEB
where PC.IPアドレス = WEB.IPアドレス and
PC.利用開始日 <= WEB.アクセス日時
union
select PC.利用者名,
WEB.IPアドレス,
WEB.URL,
WEB.アクセス日時
from PC管理マスターBU PC,WEB利用履歴 WEB
where PC.IPアドレス = WEB.IPアドレス and
WEB.アクセス時間 between PC.利用開始日 and PC.利用終了日
(例)select WEB.IPアドレス,
WEB.URL,
WEB.アクセス日時
from WEB利用履歴 WEB
where WEB.IPアドレス in
( select PC.IPアドレス
from PC管理マスター PC
where 利用者名 like '大川%' );
上記の例は、利用者名が‘大川’で始まるPCのIPアドレスを取得し、そのIPアドレスからのWEB利用履歴を選択している。
*参考*
上記の例は、副問合せを使用しない形でも可能である。
select WEB.IPアドレス,
WEB.URL,
WEB.アクセス日時
from PC管理マスター PC, WEB利用履歴 WEB
where WEB.IPアドレス = PC.IPアドレス and
PC.利用者名 like '大川%';
(例)select WEB.IPアドレス,
WEB.URL,
WEB.アクセス日時
from ( select IPアドレス
from PC管理マスター
where 利用者名 like '大川%' ) PC,
WEB利用履歴 WEB
where WEB.IPアドレス = PC.IPアドレス;
結果は、1.4.1の例および参考のものと同じである。
TOPへ
演算子 四則演算(+、-、*、/)
文字列結合(||)select 項目名||','||項目名 from テーブル名;
はよく使われる型変換関数 to_number
to_char
to_date
・・・などOracleでは暗黙の型変換があるが、明示した方がよい 演算関数 round
sign
ln
・・・など文字関数 substr
length
replace
・・・など漢字を扱う場合、substrとsubstrb、lengthとlengthbの働きの違いに注意 日付関数 sysdate
add_months
trunc
next_day
・・・など(date型データ + 1) としたときは、1日加算したことになる グループ関数
(group by句が必要)count
avg
sum
max
・・・などその他の関数 nvl
dump
decode
・・・など
(例)PC管理者マスターにあるデータの件数を表示する。結果は1件である。select count(*)
from PC管理マスター;
(例)PC管理マスターに登録されている人ごとの所有PC台数の一覧を出す。select 利用者名,
count(*)
from PC管理マスター
group by 利用者名;
(例)PC管理マスターに登録されている人数を出す。select count(count(*))
from PC管理マスター
group by 利用者名;
*参考*
group by句は、単に重複行を一つにまとめる場合にも使用されるが、その場合は、
group byは使わずdistinctを使用するほうが個人的には良いと思う・・・
(例)PC管理マスターに登録されている人数を出す。TOPへselect count(distinct 利用者名)
from PC管理マスター;
(例)PCを2台以上所有している人の一覧TOPへselect 利用者名,
count(*)
from PC管理マスター
having count(*) >= 2
group by 利用者名;
(例)nvlを利用してPC利用者名がnullだったときは‘だれか’と表示。select nvl(PC.利用者名,'だれか'),
WEB.IPアドレス,
WEB.URL,
WEB.アクセス日時
from PC管理マスター PC,
WEB利用履歴 WEB
where PC.IPアドレス(+) = WEB.IPアドレス and
( PC.利用開始日 is null or
PC.利用開始日 <= WEB.アクセス日時 );
(例)decodeを使用して、アクセス日時を週ごとに丸め、何週前のアクセスか表示。select nvl(PC.利用者名,'だれか'),
WEB.IPアドレス,
WEB.URL,
decode(trunc(WEB.アクセス日時,'D'),
trunc(sysdate,'D'), '今週',
trunc(sysdate-7,'D'), '先週',
trunc(sysdate-14','D'), '先々週',
'それ以前')
from PC管理マスター PC,
WEB利用履歴 WEB
where PC.IPアドレス(+) = WEB.IPアドレス and
( PC.利用開始日 is null or
PC.利用開始日 <= WEB.アクセス日時 );
(例)decodeを使用して、IPアドレスごとに、週ごとのアクセス数を並べて表示。select WEB.IPアドレス,
count(decode(trunc(WEB.アクセス日時,'D'),
trunc(sysdate,'D'),0,1) 今週のアクセス数,
count(decode(trunc(WEB.アクセス日時,'D'),
trunc(sysdate-7,'D'),0,1) 先週のアクセス数,
count(decode(trunc(WEB.アクセス日時,'D'),
trunc(sysdate-14,'D'),0,1) 先々週のアクセス数,
count(decode(sign(trunc(WEB.アクセス日時,'D') - trunc(sysdate-14,'D')),
-1,1,0 )) それ以前のアクセス数,
count(*) 合計アクセス数
from PC管理マスター PC,
WEB利用履歴 WEB
where PC.IPアドレス(+) = WEB.IPアドレス and
( PC.利用開始日 is null or
PC.利用開始日 <= WEB.アクセス日時 );
TOPへ
結果は以下のようになるはず・・・IPアドレス 今週の 先週の 先々週 それ以 合計ア
--------------- ------ ------ ------ ------ ------
202.26.90.92 4 15 10 21 50
202.26.90.90 10 12 5 4 31
・・・・・
(例)PC管理マスターを利用者名順の降順、IPアドレス順にソートTOPへselect *
from PC管理マスター
order by 利用者名 desc,IPアドレス;
(例)WEB利用履歴のアクセス日時が最近のもの50件を表示select WEB.IPアドレス,
WEB.URL,
WEB.アクセス日時
from WEB利用履歴 WEB
where ROWNUM <= 50
order by WEB.アクセス日時 DESC;
グループ関数を利用した場合、グループにまとめられる前にROWNUMはつけられるため、from句での副問合せを使用する。
(例)IPアドレスごとのアクセス回数が多いもの上位50件を表示TOPへselect IPアドレス,
cnt
from ( select IPアドレス,count(*) cnt
from WEB利用履歴 ) WEB
where ROWNUM <=50
order by cnt DESC
(例)今日の日付を表示する。select sysdate from dual;
*注意*
ROLLBACKしないでOracleからの接続を切り離した場合、自動的にCOMMITされる。
また、データ定義文(テーブルの構造を変更させる、権限の付与や剥奪をするなど)を実行した場合もCOMMITが働くため、注意が必要である。
またOracleではロック管理を行っており、他のトランザクションでのデータ操作がCOMMITまたはROLLBACKされるまでは、データ操作を行おうとしてもロック待ちの状態になる。
*参考*
通常、データベースの管理者は各ユーザーごとに権限のレベルを設定し、行える操作を制限している。
TOPへ
検索ユーザー :selectのみ 一般ユーザー :select,insert,update,deleteなどのデータ操作が可能
開発ユーザー :一般ユーザーに加えて、create table,create view,create functionなどが可能
(CONNECT,RESOURCEのロールと、必要ならばcreate snapshotなどの権限が付与されているユーザー)管理ユーザー :データベース管理に必要な全ての行為が可能
(systemユーザー、またはDBAロールが付与されているユーザー)
(基本形)insert into テーブル名 [(項目名[,項目名・・・])]
values ( 式[,式・・・] );insert into テーブル名 [(項目名[,項目名・・・])]
副問合せ;
(例)PC管理マスターに新しいPCを登録するinsert into PC管理マスター
( IPアドレス, 利用者名, PC名, 利用開始日)
values ( '210.26.90.92','大川','fmtf012',sysdate);
(例)PC管理マスターBUにPC管理マスターの内容を退避する。insert into PC管理マスターBU
( select *,sysdate from PC管理マスター where 利用者名 = '大川' );
*注意*
テーブルには、主キー制約や、外部キー制約、not NULL指定などの各種の制約をつけることが可能であるため、実行時にはそれらの制約に注意をしておかなければ実行時にエラーとなる。
(基本形)delete from テーブル名
where 条件;
deleteでは、テーブル名は一つしか指定できない。
条件に関してはselect文と同様であり、副問合せの使用も可能。
(例)PC管理マスターからレコードを削除delete from PC管理マスター
where 利用者名 = '大川';
(例)PC管理マスターから、PC管理マスターBUにも存在するレコードを削除delete from PC管理マスター PC1
where ( PC1.IPアドレス, PC1.利用開始日 ) in
( select PC_B.IPアドレス, PC_B.利用開始日
from PC管理マスターBU PC_B
where PC_B.IPアドレス = PC1.IPアドレス and
PC_B.利用開始日 = PC1.利用開始日 );
*注意*
where句を指定しないと、全ての行が削除されてしまう
(基本形)update テーブル名
set 項目名 = 式 [,項目名 = 式 ・・・]
where 条件;
update文も、delete文同様、テーブル名は一つしか指定できない。
条件に関してもselect文と同様であり、副問合せの使用も可能。
複数の項目の更新は、set句以降でカンマによって並べることで一度に行える。
(例)PC管理マスターの利用者名を変更するupdate PC管理マスター
set 利用者名 = '太川'
where 利用者名 = '大川';
*注意*
where句を指定しないと、全ての行が変更されてしまう
set句の式に対しても副問合せの使用が可能であるが、戻ってくる結果は、1項目、1行になるように限定される。
(例)PC管理マスターのIPアドレスが'210'で始まるものは全て'192'に置換えTOPへupdate PC管理マスター PC1
set PC1.IPアドレス
= ( select '192'||substr(PC2.IPアドレス,
instr(PC2.IPアドレス,'.',1,1))
from PC管理マスター PC2
where PC1.IPアドレス = PC2.IPアドレス
)
where PC1.IPアドレス like '210%';
> sqlplusと入力する。
対話式ではなく、直接ユーザーIDとパスワードを指定して、sql*plusの環境に入ることもできる。
> sqlplus scott/tiger
コマンドラインからスクリプトを実行することもできる。
TOPへスクリプトの作成
> echo 'select * from tab;' > script1.sql
> echo 'exit;' >> script1.sql
sql*plusで実行
> sqlplus scott/tiger @script1
TOPへバッファの内容のファイルへの書き出し
SQL> save ファイル名
ファイルからバッファへのSQL文の読み込み
SQL> get ファイル名
スクリプトファイルの実行
SQL> start ファイル名 または
SQL> @ファイル名
TOPへバッファの確認
SQL> l
バッファを実行
SQL> / または
SQL> r
エディタを利用したバッファの編集
SQL> edit
編集に使用するエディタの確認
SQL> define _EDITOR
編集に使用するエディタの設定
SQL> define _EDITOR=vi
TOPへカレント行の移動
SQL> 行番号
カレント行を最終行に移動
SQL> l last
カレント行の行末にステートメントを追加
SQL> a ステートメント
カレント行の次に行(ステートメント)を追加
SQL> i ステートメント
指定行を削除
SQL> del 行番号 行番号行番号を全て省略したときはカレント行のみ、
後ろの行番号を省略したときは指定行のみ、
両方とも行番号を指定したときはその範囲が削除される
指定行を上書き
SQL> 行番号 ステートメント
バッファ全体のクリア
SQL> clear buff
SQL> spool on ファイル名
SQL> spool off
データファイルとして利用する場合の設定例
SQL> ttitle off /* タイトルを出さない */
SQL> btitle off /* タイトルを出さない */
SQL> set head off /* 見出しを出さない */
SQL> set PAGES 0 /* ページの切り替えをしない */
SQL> set LINES 255 /* 1行の文字数を255に制限 */
SQL> set COLSEP ',' /* 項目の区切りを','に変更 */
SQL> set FEEDBACK off /* 件数の表示をしない */
SQL> col 項目名 format a20 truncate /* 文字型項目のフォーマット指定 */
SQL> col 項目名 format 999,999,999 /* 数値型項目のフォーマット指定 */
(例)利用者名の入力要求をして、PC管理マスターの検索結果を表示する
変数は、acceptで入力する以外に、定義して使うこともできる。スクリプトファイルの中身
set verify off /* 変数と値との置換結果の報告を抑制する */
set pau on /* 画面ごとで出力を停止させる */
set pau '-- Push Enter key' /* 画面切替え時のメッセージの設定 */
clear screen /* 画面のクリア */
prompt *** PC管理マスターの検索 *** /* メッセージの表示 */
accept uname prompt "利用者名の入力:" /* 変数への入力要求 */
select * from PC管理マスター
where 利用者名 like '%&uname%'; /* 変数を使用したSQL文 */exit; /* SQLPLUSの終了 */
(例)SQL> define uname = "大川"
定義も、acceptも指定していない変数は、sql*plusが自動的に入力の要求を行う。
(例)コマンドラインからのスクリプトの実行において、変数への入力の要求に対して、引数として渡すことができる。SQL> select * from tab where tname like '%&tname%';Enter value for tname:
(例)TOPへ> sqlplus scott/tiger @script1 大川
(基本形)TOPへSQL> break on 項目名 report
SQL> compute sum of 項目名 on 項目名 report
SQL> compute count of 項目名 on 項目名 report
TOPへコマンド構文を調べる
SQL> help コマンド
UNIXコマンドを実行
SQL> !ls
スキーマの定義を調べる
SQL> desc スキーマ