プログラミング言語SML#解説 3.7.1版
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⟩

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

  • •

    ⟨updateRow⟩の⟨lab⟩は 全て互いに異なっていなければならない.

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 トランザクションの中断