§ 11.2. SML#へのSQL式の導入
SQLのSELECT文はFROM節に記述されたテーブルの集合から 一つのテーブルを作成する式です. SQL言語は,ある特定のデータベースへの接続の下でSQL式を評価する機 能を提供しますが,これをデータベース接続を受け取りテーブルを返す関数式に 一般化すれば,関数型言語の型システムに統合することができます. テーブルはレコードの構造をしているため,多相レコードの型付けがほ ぼそのまま使用できます. しかし我々SML#チームの研究によって,このデータベースを受 け取る関数の型付けには,多相レコード以外にさらに型理論的な機構が必要であ ることが示されています[13]. そこで,データベース接続を受け取る関数には特別の文法を用意します. SML#では,前節のSQL式の例は,以下のような式で表現されます.
_sql db => select #P.name as name, #P.age as age
from #db.Persons as P
where SQL.>(#P.salary, 10000)
_sql db => ...は,データベース接続を変数dbとして受
け取る問い合わせ関数であることを示しています.
SQL.>はデータベース問い合わせを実現するライブラリモジュー
ルSQLの中に定義されたSQLの値のための大小比較プリミティブです.
#P.NameはタプルPのNameフィールドの取り出し演算,
#db.PersonsはデータベースdbからのPersonsテーブル取り
出し演算です.
これらは,SML#式では#Name P#Persons dbと書か
れるレコードからのフィールド取り出し式に相当します.
_sql
val it = _
: ['a#{Persons: 'b},
'b#{age: 'f, name: 'd, Salary: int},
'c,
'd::{int, word, char, string, real, 'e option},
'e::{int, word, char, bool, string, real},
'f::{int, word, char, string, real, 'g option},
'g::{int, word, char, bool, string, real}.
('a, 'c) SMLSharp_SQL_Prim.db
-> {age: 'd, name: 'f} SMLSharp_SQL_Prim.query]
この型は,'aの構造を持つデータベース接続の型('a, 'c) dbから{age: 'd, name: 'f} query型への関数型です. 'aは,この問い合わせに必要なデータベース構造を表すレコード 多相型です. 型変数'cは,データベース接続の一貫性を保証するために導入さ れたものです. このようにSQL式は多相型を持つため,MLプログラミングの原理「式は 型が正しい限り自由に組み合わせることができる」に従って,第一級のデータ としてSML#の他の機能とともに自由にプログラムすることができます.