[デザインパターン/永続化]

SQL UTILITY

平澤 章
Ver 0.1 - 1999/3/11

1 目的

リレーショナルデータベースを使ったシステムにおいて、SQL文字列の生成ロジックを容易にする。

2 別名

3 動機

事務処理アプリケーションでは、オブジェクト指向言語を使って実装する場合でも、しばしばデータベースエンジンにリレーショナルデータベースが利用される。

リレーショナルデータベースに対するアクセスは、SQL文によって行われるが、このSQL文字列を生成するロジックは単調なものの、冗長であり、メソッドが肥大化しやすい。SQL文字列はカンマやスペース、カッコの記述規則やデータ項目の記述形式などに細かいルールがあり、これを誤るとシステムは正しい動作をしない。しかし埋め込みSQLを使用しない限りはSQLシンタクスの妥当性検証は実行時に行われるため、コーディング段階で妥当性を確認することができない。

4 適用可能性

SQL UTILITYパターンは、次のような場合に適用することができる。

5 構造

SQL Utility Class Diagram

6 構成要素

7 協調関係

SQLUtilは単にSQLの文字列を生成だけを行う。DBMSエンジンへの要求の発行や結果の解析は、クライアント側の責任である。

8 結果

8.1 メリット

  1. バグの減少
    SQL文字列を生成するロジックの品質が安定し、バグが減る。
  1. Clientロジックの簡略化
    Clientオブジェクトのロジックが簡略化され、見通しが良くなる。

8.2 留意点

  1. クエリーの条件文字列
    帳票出力などを目的としたクエリーでは、さまざまな条件を指定する場合があり、このようなケースについて汎用的なメソッドを提供するのは難しい場合が多い。この場合は、SELECT文に指定する項目名だけをSQLUtilで生成し、WHERE句についてはClient側で付加する必要がある。

9 実装

9.1 データ型の判定

SQLではデータを指定するのに、文字列データについては 'ABC' のようにシングルクォーテーションで囲い、数値データについては 123 のようにそのまま指定する必要がある。
SmalltalkやJava、Visual Basicのように、ObjectやVariantといった総称的な型を使用できるプログラム言語の場合は、クライアントから渡されたデータの型をSQLUtil側で判定して適切な文字列を生成することができる。

9.2 データの格納形式への自動変換

エンドユーザーコンピューティングなどの目的でデータベースを直接アクセスさせるために、オブジェクト上は真偽値(Boolean)として保持している属性をデータベース内では '0', '1' などの文字データとして保持することがよくある。
このパターンを使うことで、このようなデータの格納形式をクライアントアプリケーションから隠蔽することができる。ただしこの場合、永続記憶からオブジェクトを復元する時のために、データの格納形式から本来の属性値に変換するためのメソッドを併せて提供する必要がある。

10 サンプルコード

以下は、Visual BasicによるGet InsertStrメソッドの例である。

===
Public Function GetInsertStr(tblName As String, _
colNames() As String, _
values() As Variant) As String

Dim sqlBuffer As String 'SQL文字列格納バッファ
Dim i As Integer 'カウンタ

'"INSERT INTO テーブル名 (項目名、項目名)"までを生成
sqlBuffer = "INSERT INTO " & tblName & " ("
For i = LBound(colNames) To (UBound(colNames) - 1 )
sqlBuffer = sqlBuffer & colNames(i) & ", "
Next
SqlBuffer = sqlBuffer & colNames(UBound(colNames)) & ")"

'VALUES以降を生成
sqlBuffer = sqlBuffer & " VALUES ("
For i = LBound(values) To (UBound(values) - 1)
sqlBuffer = sqlBuffer & GetValueString(values(i)) & ", "
Next
SqlBuffer = sqlBuffer & GetValueString(values(UBound(values))) & ")"

'作成した文字列をリターン
GetInsertStr = sqlBuffer
End Function

11 使用例

某社会計システム
某社在庫&販売管理システム

12 関連するパターン

13 参考文献

[1] Gamma, E. et al. Design Patterns: Elements of Reusable Object-Oriented Software, Addison-Wesley, 1995