プログラミング言語SML#解説 4.0.0版
22 SQL式とコマンド

22.6 SQLコマンド

SML#は,SELECTクエリに加え, 以下の規則で定義されるSQLコマンドのサブセット sqlcommandを受け付ける.

sqlcommand ::= sqlinsert INSERTコマンド
 | sqlupdate UPDATEコマンド
 | sqldelete DELETEコマンド
 | sqltransaction トランザクション関連コマンド
 | (sqlfn; ; sqlfn) コマンドのシーケンス
 | ... ( exp ) SQLコマンドの埋め込み

INSERT,UPDATE,DELETE,トランザクション関連コマンドの型は,

(unit, w) SQL.command

である. 各コマンドの詳細は以下の各副節で与える.

(sqlfn1; ; sqlfnn)nは2以上でなければならない)は,一度に送信される セミコロンで区切られた一連のコマンドを表す. その型は最後のコマンドsqlfnnの型に等しい.

...(exp)は,SML#の式を評価した結果を コマンドとして埋め込む.

22.6.1 INSERTコマンド

INSERTコマンドの構文は以下の通りである.

sqlinsert ::= insert into #vid.lab  (lab, , lab)
values insertRow, , insertRow
 | insert into #vid.lab  (lab, , lab)
values insertVar
 | insert into #vid.lab  ((lab, , lab))? sqlselect
insertRow ::= (insertVal, , insertVal)
insertVal ::= sqlexp  | default
insertVar ::= vid  | op longvid

以下の構文上の制約がある.

  • (lab, , lab)に現れるラベルは 全て互いに異なっていなければならない.

  • insertRowに現れる insertValの数は, (lab, , lab)のラベルの数と 一致しなければならない.

INSERTコマンドは, values句で指定された各行あるいは sqlselectクエリの評価結果の各行を, 指定したテーブルに挿入する. values句にSML#の変数 vidまたはop longvidを書いた場合, ラベルlab1, , labnを持つ レコードのリストをテーブルに挿入する. 挿入しようとしている行が挿入先テーブルのカラムを網羅していないとき, 指定のないカラムには,テーブル作成時に指定されたデフォルト値が 挿入される. また,values句にdefaultと書かれている箇所についても デフォルト値が挿入される. カラムにデフォルト値が設定されていないときは, コマンドを評価するサーバーで実行時エラーが発生し, SQL.Exec例外が発生する.

型の制約は以下の通りである.

  • vidはテーブル名labを含む SQL.db型でなければならない.

  • (lab1, , labn)が 書かれているとき, #vid.labが指示するテーブルおよび sqlselectは,少なくとも カラム𝑙𝑎𝑏1,,𝑙𝑎𝑏nを 持っていなければ ならない. それ以外のカラムを持っていても良い. また, 挿入先テーブルとsqlselectクエリのカラム集合が 一致していなくてもよい.

  • (lab1, , labn)が 書かれていないとき, 挿入先テーブルとsqlselectクエリのカラム集合は 一致しなければならない.

  • values句に並ぶ各組のi番目の式sqlexpiの型は, 挿入先テーブルのカラムlabiの型がτiのとき, ({},w)τi型でなければならない.

22.6.2 UPDATEコマンド

UPDATEコマンドの構文は以下の通りである.

sqlupdate ::= update #vid.lab
set updateRow, , updateRow
(sqlWhereClause)?
updateRow ::= lab = sqlexp

以下の構文上の制約がある.

  • updateRowlabは 全て互いに異なっていなければならない.

UPDATEコマンドは,指定したテーブルのうち WHERE句の条件を満たす行を, SET句の値で更新する. SET句で指定されていないカラムは更新されない. 新しい値を計算する式には, 更新前の行の値を参照するために, labをテーブル名とする カラム参照式を書いても良い.

型の制約は以下の通りである.

  • vidはテーブル名labを含む SQL.db型でなければならない.

  • updateRowiで指定されるカラムlabiは すべて更新先テーブルに含まれていなければならない. 更新先テーブルはそれ以外のカラムを持っていても良い.

  • updateRowiの式sqlexpiの型は, 更新先テーブルの行の型がτ,カラムlabiの型がτiのとき, ({𝑙𝑎𝑏 : τ},w)τi型で なければならない.

  • sqlWhereClauseは,存在するならば, 更新先テーブルの型がτのとき, (τ -> τ, w) SQL.whr型でなければならない.

22.6.3 DELETEコマンド

DELETEコマンドの構文は以下の通りである.

sqldelete ::= delete from #vid.lab (sqlWhereClause)?

DELETEコマンドは指定したテーブルのうち WHERE句の条件を満たす行を削除する.

型の制約は以下の通りである.

  • vidはテーブル名labを含む SQL.db型でなければならない.

  • sqlWhereClauseは,存在するならば, 更新先テーブルの型がτのとき, (τ -> τ, w) SQL.whr型でなければならない.

22.6.4 BEGIN,COMMIT,ROLLBACKコマンド

SML#は,トランザクションを制御するコマンドのうち, 以下のコマンドをサポートする.

sqltransaction ::= begin トランザクションの開始
 | commit トランザクションの終了
 | rollback トランザクションの中断