データアクセスAPIのSQL平準化
データディレクトは、あらゆるオープンデータアクセスAPIに渡って、SQLを平準化します。このため開発者は、バックエンドのDBMSに関係なく同じコードを使用して、共通の方法で上記のような機能を実装できます。
概 要
APIのSQL平準化
エスケープ節とSQL拡張
日付と時刻のリテラル
外部結合
スカラー関数
ストアドプロシージャの呼び出し
動的SQL文のフォーマット修正
空文字列とNULLの変換
長い文字列の挿入サポート
まとめ
概 要
データディレクト テクノロジーズは、業界リーダーとして、 データベース間の最高レベルの相互運用性を企業にご提供し続けてきました。相互運用性における主要事項の一つに "SQLの平準化" があります。これは、データベースのSQL実装に左右されることなく、複数のデータベースに渡って実行可能なSQL文を記述できることを意味します。たとえば、Oracle用に記述されたSQL文をDB2でも使うことができます。
主要なDBMSベンダは、ANSI SQL標準をサポートしています。しかし、ある特定の機能に関しては、それぞれのデータベースがそれぞれに固有な形式で実装しています。形式が異なる機能は、次のように分類できます。
- 日付と時刻のリテラル表現
- 外部結合の構文
- スカラー関数の構文
- ストアドプロシージャの呼び出し
- 動的SQL文のフォーマット修正
- 空文字列とNULLの変換
- 長い文字列の挿入サポート
データベースごとに異なるSQL実装は、オープンデータアクセス標準がめざす相互運用性にも影響を与えます。オープンな標準を適用すれば、 データベース間の相互運用性を高水準で実現できるため、企業が負担するコストも削減できます。しかし、SQLの相互運用性を実現できないと、その企業はオープンな標準を使うメリットを十分に享受できません。
APIのSQL平準化
SQLの平準化は新しい概念ではなく、データディレクトでは初期の製品から採用しています。ODBCデータアクセス標準では、SQLの平準化は "エスケープ節" を使用して実装されました。このエスケープ節は、ある特定の機能を、データベースベンダが実装するSQL標準に左右されることなく実行するための文法を提供します。後に、クロスプラットフォームの開発環境としてJavaが登場すると、Sunはエスケープ構文をJDBC APIにも実装し、データベース間の相互運用性を提供しました。しかし、ADO.NETデータアクセス標準は、SQLの平準化を行いません。.NETフレームワークでは、ADO.NETデータプロバイダがデータベース固有のSQL機能を標準的な方法で実装することを要求していません。このADO.NET標準の難しい制約は、2004年12月に予定される .NET Framework Version 2.0 (コードネームWhidbey)でも残る見込みです。
データベースベンダの.NETプロバイダを使用する開発者は、SQLの平準化による相互運用性を求めているならば失望することでしょう。なぜなら、これらのプロバイダは、ある特定の機能を実現するSQLを、それぞれに固有な形式で実装しているからです。また、これらのプロバイダは完全なマネージドコードだけで実装されていないため、パフォーマンスも低下します。さらに開発者は、パフォーマンスの影響を受けるだけでなく、複数のデータベースにアクセスするプロジェクトで複数のコードを使い続ける必要があります。
データディレクト テクノロージーズは、この.NETフレームワークの欠点を、すべてのDataDirect Connect for .NETマネージドプロバイダで、SQL平準化を実装することによって克服しました。データディレクトのプロバイダは、完全なマネージドコードだけで記述されています。このため開発者は、データベースの真の相互運用性を得られるだけでなく、完全なマネージドコードによって、 .NETフレームワークが提供するパフォーマンスやセキュリティ機能を活用することができます。
エスケープ節とSQL拡張
SQL拡張は、オープンデータアクセス標準独自のSQL標準に対する拡張です。SQL拡張は、SQL平準化の一貫した方法を提供することによって、いろいろなデータベースで使用できるSQLの機能にアクセスするものですが、SQL標準には含まれていません。SQL拡張(以降、エスケープ構文)は、データベースで共通したSQL文を利用したい開発者に、高い相互運用性を与えます。データベースベンダは、概して、これらの機能を固有なSQL拡張として実装しています。これに対してエスケープ構文は、利用するデータベースに依存せず、共通した標準的な形で使用できます。
エスケープ構文は、データベースの解釈で特別な処理を必要とする場合がある、SQL文をスキャンするための簡単な方法を、ドライバならびに(または)プロバイダに提供します。これは、ODBC、JDBC、DataDirect .NET プロバイダのエスケープ節を介して実行されます。エスケープ節は、SQL文を囲む中括弧 "{ }" と、エスケープ節の型を示す1~2文字の識別子から成ります。データアクセスのコンポーネント(ODBC、JDBCドライバ、.NETプロバイダ)は、これらのエスケープ節をデータベースが解釈できる構文に変換する必要があります。こうすることで、アプリケーション中でSQL文を最大限に活かしたい開発者は、データベースの実装に左右されることなく、高い相互運用性を得ることができます。以下のセクションでは、エスケープ節に固有な実装と、その使用方法を説明します。
日付と時刻のリテラル
主要なデータベースはすべて、程度の差こそあれ、データ型DATE、TIME、TIMESTAMPまたはDATETIMEをサポートしています。日付と時刻の形式は、データベースベンダによって実にさまざまな形で提供されているため、開発者が利用する場合には一貫性が取れません。良い例がDATEの形式で、Oracleでは mm dd, yyyy ですが、DB2では yyyy-mm-dd となります。このようにさまざまな実装があるため、複数のデータベースにアクセスするアプリケーションで日付を使おうとする場合に問題となります。SQL標準が定義するDATEのデータ形式は yyyy-mm-dd で、エスケープ節で実装する方法と同じです。アプリケーションの開発者が複数のデータベースでDATEのデータ形式を使う場合、{d 'yyyy-mm-dd'} と記述します。
たとえば、2003年10月11日または2003年10月15日に入社した従業員を選ぶSQL文を記述する場合には、以下のようなSQL文を使用します。
SELECT EmpName, HireDate
FROM Emp
WHERE HireDate = {d '2003-10-11'}
OR HireDate = {d '2003-10-15'}
データディレクトのOracle JDBCドライバは、この構文を以下のように変換します。
SELECT EmpName, HireDate
FROM Emp
WHERE HireDate = 'Oct 11, 2003'
OR HireDate = 'Oct 15, 2003'
データディレクトのSQL Server JDBCドライバは、この構文を以下のように変換します。
SELECT EmpName, HireDate
FROM Emp
WHERE HireDate = '10-11-2003'
OR HireDate = '10-15-2003'
TIMEとTIMESTAMPにも、エスケープ節があります。 リテラルの文法にはSQL標準の形式を使い、エスケープ節でそれぞれ 't' または 'ts' の文字記号で示します。したがって、TIMEは {t 'hh:mm:ss'} 、TIMESTAMPは {ts 'yyyy-mm-dd hh:mm:ss'} になります。以上のようなDATE と TIME のエスケープ構文は、データディレクトの全製品があらゆるデータアクセスAPIに渡って同じ方法で実装しています。このため開発者は、 JDBC、ODBC、ADO.NETはもちろん、異なるベンダのデータベースでも、一つのSQL文を使用するだけで済みます。
外部結合
日付と時刻のリテラルと同じく、外部結合の実装もデータベースベンダによって異なり、あるデータベースと他のデータベースとでは一貫性が取れていません。外部結合は、二つのテーブルのレコードを一致させる時に便利な方法で、二つの異なるテーブルから関連する行の組み合わせを作るものです。外部結合は、内部結合とは違うやり方をします。データに一致する組み合わせがない場合、内部結合では行を戻しませんが、外部結合では行にヌル値のカラムを戻します
外部結合はエスケープ節で実装され、構文は以下のようになります。
{oj table1 LEFT|RIGHT|FULL OUTER JOIN table2 ON search condition}
Raleighという都市にある営業所の全営業担当者を示すクエリーを記述する場合、外部結合のエスケープ構文は以下のようになります。
SELECT emp.EmpName, office.City
FROM {oj emp LEFT OUTER JOIN office ON emp.EmpId =office.EmpId}
WHERE emp.City = 'Raleigh'
エスケープ構文を使用するデータディレクトのOracle .NETプロバイダは、 これを以下のように変換します。
SELECT emp.EmpName, office.City
FROM cust, ord
WHERE emp.EmpId =office.EmpID (+) AND emp.City = 'Raleigh'
データディレクトのSQL Server .NETプロバイダは、以下のように変換します。
SELECT emp.EmpName, office.City
FROM emp, office
WHERE emp.EmpId *= office.EmpId AND office.city = 'Raleigh'
開発者は、複数のデータベースにアクセスするアプリケーションでSQL文を最大限に活用したいと考えています。しかし、データベースベンダは共通した構文を実装していないため、複雑になりがちな外部結合の構文でSQLを平準化する必要性はますます高まっています。
現在入手できる .NETプロバイダのほとんどは、このようなSQLの平準化機能をサポートしておらず、.NETフレームワークでもサポートされていません。データディレクトは、SQLの平準化機能の実装経験をConnect for ADO.NET プロバイダにも活かし、開発者がSQL文の移植性を最大化できるようにしています。
スカラー関数
エスケープ節で提供される他の機能と同様に、スカラー関数も、データベースベンダごとにさまざまな固有の形式で実装されています。スカラー関数も、エスケープ構文を使用すれば、異なるデータベースに渡って一貫した方法で実行できます。スカラー関数は一つの値に対して実行されるもので、値のセットで実行される集合的な関数とは対照的です。スカラー関数には大きく分けて、数値、文字列、日付と時刻、システムという四つの形があります。データディレクトの製品ラインは、これらのスカラー関数をあらゆるAPIに渡って一貫した方法で実装し、開発者がデータベースに関係なく、できるだけ多くのSQL文を再利用できるようにしています。
数値関数
数値関数は、サイン、コサイン、平方根、絶対値、対数など、数学的な値を定義する機能を提供するものです。サポートしている関数はこれら以外にも多数あり、いずれも、データベースの実装とは無関係に、エスケープ節を使って呼び出すことができます。ただし、データアクセスコンポーネントは、データベースのバックエンドで利用可能な関数へのアクセスしか提供できません。以下は、平方根の関数を呼び出す方法を示したものです。
Select {fn SQRT(c_squared)} from table1 where shape='triangle' and type='isosceles'
文字列関数
文字列関数を使うと、開発者は、SQL結果セット中で文字列を動的に操作できます。たとえば、すべての文字を大文字に設定したり、文字列の始めか終わりの部分を戻したりすることができます。利用できる文字列関数には、UCASE、LCASE、RTRIM、LTRIM、 LENGTH、SUBSTRINGなどがあります。以下の構文は、データベース中の大小文字が混在する行にUCASE値を戻すものです。
Select {fn UCASE(LastName)} from emp where office = 'Raleigh'
日付と時刻の関数
開発者が日付や時刻の値を操作したり、SQL文で使う曜日や現在時刻を取得する必要がある場合、日付と時刻の関数が便利です。以下の例は、DAYNAME関数を使用して、顧客 Progress が注文した日付と曜日を取得するものです。
select date,{fn DAYNAME(date)} from orders where customer='Progress'
システム関数
システム関数に含まれるのは、データベース名や現在接続しているユーザ名を取得する機能や、ヌル値を確認してNULLとなっている場合に他の値に置き換える機能などです。以下の例は、SELECT文でUSER関数を使用して、現行ユーザのすべての休暇日を取得するものです。
Select VacationDays from emp where EmpName={fn USER()}
ストアドプロシージャの呼び出し
一般的に開発者は、アプリケーションのパフォーマンスを最大化するために、できるだけストアドプロシージャを使います。ストアドプロシージャの構文は、データベースごとにさまざまな固有の形式で実装されており、ストアドプロシージャに引数として受け入れられるパラメータには、異なるマーカーが使用されています。データディレクトは、あらゆるデータアクセスAPIに渡って一貫するエスケープ構文を提供しています。ストアドプロシージャの呼び出しに使用するエスケープ構文は、{call プロシージャ名 (?,?)} となり、"?" には、ストアドプロシージャがパラメータを使用する場合のパラメータマーカーが入ります。パラメータマーカー "?" は、市販されるデータベースやAPIの全主要ブランドで使用できます。このため、ストアドプロシージャの呼び出しコードは、異なるデータベースにアクセスしても変更する必要はありません。以下の例は、ある国の固定資産税率を戻すストアドプロシージャを呼び出すものです。国名のパラメータを受け入れます。
{CALL county_prop_tax (?)}
この場合、パラメータはユーザーが指定した国名となります。このような方法でストアドプロシージャを呼び出すと、開発者は、さまざまなデータベースやデータアクセスAPIに渡って一貫した形式でストアドプロシージャを呼び出すことができ、パフォーマンスも最大化できます。
動的SQL文のフォーマット修正
データベースによっては、引数、演算子、値の間隔に関して、SQL文を特定の方法でフォーマットする必要があります。たとえばDB2では、SQL文で、演算子 "=" の両側にスペースを一つ必要とします。SQL Serverなどの他のデータベースでは、このような規則はありません。データディレクト製品は、文の構造を動的に変換して、使用するデータベースに受け入れられるようにします。たとえば、以下のような形式を受け入れるSQL Serverを使用している場合、
Select EmpID from emp where LastName='Smith'
データディレクトのConnect for ODBC DB2ドライバは、これを以下のような形式に動的に変換します。
Select EmpID from emp where LastName = 'Smith'
動的なフォーマット修正の別の例として、SQL文の "newline" 文字があります。DB2などのデータベースでは、これらを使用する文字や文を認識せず、データベースの構文エラーを生成します。データディレクトのDB2向け製品は、このnewline文字を動的に空白に置き換えるので、DB2は構文エラーとならずにSQL文を処理できます。
このようにSQL同等化を実装することによって、DB2で構文エラーが発生しないことが保証されます。機能はドライバが実装しているので、開発者が何かを行う必要はありません。SQL文の構文に関するデータベース間の相互運用性は、すべてのAPIに渡って実装されており、データベース固有の文法的な要件に左右されることはありません。
空文字列とNULLの変換
SQL文をANSI標準で記述する開発者は、空文字列を示すのに、二つの一重引用符の識別子を使います。しかしながら、Oracleなどのデータベースでは、この二つの一重引用符の識別子は、ヌル値を示すのに使われています。データベースベンダが提供するデータアクセスコンポーネントを使用する開発者は、このようなコード内の違いを、別々のSQL文を記述したり、データベース固有の実装に従ってこの識別子をプログラムで変更するなどして、追跡し続けなければなりません。データディレクトでは、これを動的に変換しています。Oracleに接続するアプリケーションで、以下のような構文を使用している場合、
Insert into emp (FirstName, LastName, VacationDays) values ('Tom', 'Smith', '')
データディレクトのConnect for ODBCドライバ (Oracle版)は、この構文を以下のように変換します。
Insert into emp (FirstName, LastName, VacationDays) values ('Tom', 'Smith', "")
ヌル値は演算子を使うことはできず、ISNULLやISNOTNULL条件を使わなければなりません。これによって、データベースに正しい値が挿入され、文字列に関するすべての演算子のロジックが適用されます。
長い文字列の挿入サポート
長い文字列を挿入する場合、2,000文字までに制限するデータベースもありますが、そうでないものもあります。たとえばSybaseでは、ユーザーが2,000文字を超える文字列を挿入しようとした場合、例外が発生します。これを避けるには、データベースに挿入する前に文字列の長さを確認するか、発生した例外をとらえて文字列をまとめ、パラメータとして挿入する必要があります。DataDirect製品では、これを動的に行います。長い文字列の挿入時にデータベースで例外が発生した場合、ドライバまたはプロバイダが例外をとらえて、文字列をパラメータとして動的に挿入します。
まとめ
企業の多くがアプリケーションの移植性や開発者の生産性向上を図るために、ODBC、JDBC、ADO.NETなどのオープンなデータアクセス標準を採用しています。しかし、異なるベンダのデータベース間でSQL標準に移植性がないという実例は、いまだに存在します。データディレクトは、このデータベースおよびデータアクセスAPI間の相互運用性を、SQLの平準化によって実現しています。このため開発者は、市販されているトップブランドのさまざまなデータベースに渡って、高い移植性を持つSQL文を記述できます。これは単に開発者の生産性を高めるだけでなく、導入までの時間やアプリケーションの保守時間を短縮し、企業の投資収益を向上させることにもなります。データディレクトは、業界をリードするあらゆるデータベースとデータアクセスAPIに渡って、一貫してSQLを平準化しています。データベースの相互運用性を最大に活かしたい企業は、データディレクトを選ぶことで、その願いを実現することができます。