• タプルが増えなくなるまで再帰的に処理
親 子
織田信秀 織田信広 織田信秀 織田信長 織田信秀 織田信行 織田信長 織田信忠 織田信長 織田信雄 織田信長 織田信孝 織田信忠 織田秀信 豊臣秀吉 豊臣秀頼 徳川家康 徳川秀忠
... ...
名前 織田信忠 織田秀信
...
余談:プログラムとの連携
57
プログラムからのSQL利用(1)
クライアント
(ウェブブラウザ)
インターネット
ウェブ サーバ
・ウェブを介して 要求受付
アプリ ケーション
サーバ
DBMS
DB
・問合せ結果 をもとに 各種の処理
・HTMLに加工
・ユーザは 検索条件
(書籍名など)
を入力
・HTMLを 配信
・SQL問合せ を作成
・DBMSに発行
SQL 問合せ
問合せ 結果
• 求められる機能
– プログラム中からのSQLの発行 – 問合せ結果の受け取り
– 動的なSQLの発行:ユーザの条件指定は そのつど異なる
58
プログラムからのSQL利用(2)
• 以下のような問合せをプログ ラム内で構築
• DBMSに発行
• 結果として得られた行(タプ ル)の集合からHTMLを作成
SELECT *
FROM 書籍 x, 販売 y
WHERE x.出版年 >= 2000
AND x.タイトル LIKE ‘’%データベース%’
AND x.書籍番号 = y.書籍番号 ORDER BY y.販売数 DESC
PHP 言語の例(1)
• HTML文書のひな型にデータベース問合せ結
果を埋め込む(伝統的なPHPプログラムの例)
59
<html>
<h1>問合せ結果</h1>
$gakubu = argv[1];
<ul>
$result = exec(“SELECT 学籍番号, 氏名 FROM 学生 WHERE 学部 = $gakubu");
if ($result) { do {
@$row = fetch_row($result, $i);
if ($row) {
print('<li>'. $row[0] . ', ' . $row[1] . '</li>' . "¥n") }
} while ($row);
}
</ul>
</html>
exec( ) は,引数で与えられた SQL文を実行
$result変数には問合せ結果が入る
fetch_row( )は,問合せ結果から 次の1行を読み込む
print( ) で出力する
‘.’ は文字列を結合することを表す
“¥n” は改行文字
プログラムの引数で変数$gakubuを初期化
PHP 言語の例(2)
• 先のプログラムはHTMLのテンプレートで,$ で始まる部分はHTML言語ではない
• ウェブ経由で問合せ条件が来ると,先のPHP プログラムをPHP言語処理系で解釈
– $~の部分をPHP言語のルールで処理 – 問合せ条件($gakubu)に
変数を代入し,得られたSQLを DBMSに発行
– 結果を受け取り加工して
HTMLテンプレートに埋め込む
• 結果は右図のようになる
60
<html>
<h1>問合せ結果</h1>
<ul>
<li>001, 山田一郎</li>
<li>002, 鈴木花子</li>
…
</ul>
</html>
61
埋込みSQL(Embedded SQL)
• 教科書5.6節
• プログラム中にデータベース操作処理を埋め 込む(図5.2)
• 埋込みSQLを含むプログラムをDBMS提供 のプリプロセッサで処理
– DBMSを呼び出すホスト言語の処理に置き換え
– DBMS提供のライブラリなどとリンクし実行
• C言語/C++言語では最近では用いられない
62
ODBC,JDBC,SQL/CLI
• ODBC(Open Database Connectivity)
– RDBMSにアクセスする共通インタフェースとして Microsoftが開発
– DBMSに対する一連の処理をC言語の関数として提供 – ソースレベルでのアプリケーションの可搬性を実現
• JDBC
– ODBCのJava版
– Java SEに含まれる
• SQL/CLI
– CLIはCall Level Interface(呼出しレベルインタフェース)
の略
– ODBC, JDBCの考え方をもとに,規格にまとめたもの
63
ODBCのイメージ
アプリケーション プログラム
・C言語で記述
・各種ODBC関数の 呼出しを含む
ODBCドライバ
・C言語のライブラリ
・DBMSのベンダーが 提供
コンパイル
実行プログラム
ODBC関数群
DBMS
SQL発行 問合せ結果 取得
64
JDBCの記述例
• 従業員テーブル から1行ずつ
読み出す
• 各レコードから 名前属性の値 を取り出す
• ResultSetは JDBCが提供 するクラス
…
Class JdbcSample {
…
ResultSet resultSet;
String sql = “SELECT * FROM 従業員”;
try {
resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
String name = resultSet.getString(“名前”);
System.out.println(…);
}
… }
… }
65
DBMSが提供するプログラミング言語
• OracleのPL/SQLが代表的
– PostgreSQLならPL/pgSQL
• 変数が使え,if, for, loopなどの制御構造を持つ スクリプト言語
• SQLを埋め 込みできる
• SQLのみでは 書けない簡単 な処理を記述
DECLARE
CURSOR cur IS SELECT name FROM emp;
str VARCHAR2(10);
BEGIN
OPEN cur;
LOOP
FETCH cur INTO str;
EXIT WHEN cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(str);
END_LOOP;
CLOSE cur;
END;
66
O/R マッピング(1)
• オブジェクト-リレーショナルマッピング
– ORMとも書く
• Javaなどのオブジェクト指向言語のクラスを RDBMSのテーブルに対応づける
– プログラマはSQLを直接扱わなくてよい
• 例:Ruby on RailsのActive Record
– students(id, name, age, …) というテーブルがす でにRDB上に作られていると想定
class Student < ActiveRecord::Base end
と宣言するだけで,自動的に
s = Student.new s.id = “001”
s.name = “山田一郎”
…
などと書ける
students テーブルに レコードが 挿入される
67
Ruby on Rails の Active Record (1)
• 問合せの例
s = Student.find(1)
SELECT *
FROM students WHERE id = 1 LIMIT 1
実は裏で SQLが 発行されて idが1の学生のオブジェクトを いる
見つけて変数sに代入
「LIMIT 1」は,最初に見つかった レコードを返す指示
s = Student.where(name: ‘山田一郎’).take 名前が山田一郎である学生のオブジェクトを
見つけて変数sに代入 SELECT *
FROM students
WHERE name = ‘山田一郎’ LIMIT 1
• 複雑な問合せの記述は困難
• 必ずしもよいSQL問合せが発行される とは限らない
O/Rマッピングの注意点
68
Ruby on Rails の Active Record (2)
• 関連付け:例
class Customer < ActiveRecord::Base has_many :orders
end
class Order < ActiveRecord::Base belongs_to :customer
end
CustomerとOrderが 1対多で関連する ことを示す
Customer.find(1).orders each do |o|
print(“order date: “, o.date) end
以下のようなコードが書ける
idが1の顧客による 発注のそれぞれの 日付を出力
裏で自動的に結合処理が行われる
69