Microsoft SQL Server 2005 での XML サポート
執筆者: Shankar Pal, Mark Fussell, および Irwin Dolobowsky
発効日: 2004年5月
対象: Microsoftâ SQL Serverä 2005
概要 : この資料では、SQL Server 2005 に組み込まれている XML サポートについて説明します。.NET Framework V2.0、および OLEDB や SQLXML などのネイティブ コードで、このサポートがクライアント側のプログラミング サポートとどのように統合されるのかを示します。
著作権と免責
このドキュメントは暫定版であり、このソフトウェアの最終的な製品版の発売時に実質的に変更される場合があります。
このドキュメントに記載されている情報は、このドキュメントの発行時点におけるマイクロソフトの見解を反映したものです。変化する市場状況に対応する必要があるため、このドキュメントは、マイクロソフトの確約とはみなされないものとします。 また、発行以降に発表される情報の正確性に関して、マイクロソフトはいかなる保証もいたしません。
このホワイト ペーパーは情報提供のみを目的としています。明示、黙示または法律の規定に関わらず、このドキュメントの情報についてマイクロソフトはいかなる責任も負わないものとします。
お客様ご自身の責任において、適用されるすべての著作権関連法規に従ったご使用を願います。このドキュメントのいかなる部分も、米国 Microsoft Corporation の書面による許諾を受けることなく、その目的を問わず、どのような形態であっても、複製または譲渡することは禁じられています。 ここでいう形態とは、複写や記録など、電子的な、または物理的なすべての手段を含みます。 ただし、これは、著作権法上のお客様の権利を制限するものではありません。
マイクロソフトは、このドキュメントに記載されている内容に関し、特許、特許申請、商標、著作権、またはその他の無体財産権を有する場合があります。別途マイクロソフトのライセンス契約上に明示の規定のない限り、このドキュメントはこれらの特許、商標、著作権、またはその他の無体財産権に関する権利をお客様に許諾するものではありません。
別途記載されていない場合、このソフトウェアおよび関連するドキュメントで使用している会社、組織、製品、ドメイン名、電子メール アドレス、ロゴ、人物、出来事などの名称は架空のものです。実在する会社、組織、商品、ドメイン名、電子メール アドレス、ロゴ、個人名、場所、出来事などとは一切関係ありません。
2004 Microsoft Corporation.All rights reserved.
Microsoft、ActiveX、Visual Basic、Visual Studio、および Windows は米国 Microsoft Corporation の米国またはその他の国における登録商標または商標です。
記載されている会社名、製品名には、各社の商標のものもあります。
目次
著作権と免責
目次
はじめに
XML データにリレーショナル データベースを使用する理由
SQL Server 2000 での XML サポート
SQL Server 2005 での XML サポートの概要
XML ストレージのきっかけとなるシナリオ
カスタム プロパティの管理
データ交換とワークフロー
ドキュメント管理
SQL Server 2005 でのサーバー側の XML 処理
XML データ型
テキスト エンコーディング
XML データの格納
XML データのクエリと変更
XML データのインデックスの設定
XML スキーマ処理
FOR XML の機能強化
パフォーマンスのガイドライン
SQL Server CLR での XML サポート
SQL Server 2005 でのクライアント側の XML 処理
XML データ型のクライアント側サポート
XML とリレーショナル スキーマとの間での SQLXML マッピング
XPath を使用した XML ビューのクエリ
アップデートグラムを使用した XML ビューによる更新
XML ビューによる XML データの一括読み込み
SQLXML データ アクセス メソッド
まとめ
はじめに
XML (eXtensible Markup Language : 拡張マークアップ言語) が、プラットフォームに依存しない形式のデータ表現として、幅広く採用されるようになりました。XML は、B2B (business-to-business) アプリケーションやワークフローのような状況で、疎結合の異種システム間で情報を交換するのに役立ちます。データ交換が、XML テクノロジの主要な原動力になります。
XML は、半構造化されたデータや構造化されていないデータをモデル化するために、エンタープライズ アプリケーションで使用されることが多くなってきました。このようなアプリケーションの 1 つに、ドキュメント管理があります。電子メールのようなドキュメントは、本質的に半構造化されています。ドキュメントが XML データとしてデータベース サーバーに格納されていれば、ドキュメントのコンテンツに基づいてドキュメントを取得したり、セクション名に「背景」という単語が含まれるセクションを見つけるなどのコンテンツの一部を照会したり、ドキュメント集約したりする、優れたアプリケーションを開発できます。XML を生成および使用するアプリケーションの台頭により、このようなシナリオが実現可能になります。たとえば、ユーザーは、Microsoft Office 2003 システムにより、Word、Excel、Visio、および Infopath ドキュメントを XML マークアップとして生成できます。
XMLデータにリレーショナル データベースを使用する理由
・ リレーショナル データベースに XML データを格納することにより、データ管理やクエリ処理が向上します。SQL Server では、リレーショナル データ上での優れたクエリ機能やデータ変更機能が提供されていましたが、このような機能の対象範囲が、XML データのクエリや変更に拡張されました。この拡張により、コストに基づいた最適化やデータ ストレージの分野で、以前にリリースされた SQL Server で行われた投資を活用できるようになります。たとえば、リレーショナル データベースでインデックスを設定する技法はよく知られていますが、これが XML データにインデックスを設定するように拡張されることで、コストに基づいた決定を使用して、クエリが最適化されるようになります。
・ XML データを、既存のリレーショナル データや SQL アプリケーションと相互運用できます。したがって、データ モデリングのニーズが発生したときに、既存のアプリケーションに影響することなく、XML データをシステムに導入できます。また、データベース サーバーにより、XML データを管理する機能 (バックアップ、復元、レプリケーションなど) も提供されます。
・ ますます増加する XML の使用に対処するために、SQL Server 2005 内でネイティブに XML をサポートするニーズが、このような機能を提供するきっかけとなりました。エンタープライズ アプリケーション開発では、SQL Server 2005 での XML サポートからの利点が得られます。
・ これ以降のセクションでは、SQL Server 2000 と 2005 での XML サポートの概要を説明し、XML を使用するきっかけとなるシナリオをいくつか紹介して、サーバー側とクライアント側での XML の機能セットについて詳しく説明します。
・ SQL Server 2000での XML サポート
ここでは、SQL Server 2000 での XML サポートの概要を簡単に説明し、その後、リレーショナル データと XML との間での相互マッピングの豊富なサポートを提供する、SQLXML クライアント側プログラミング プラットフォームの Web リリースについて説明します。
・ サーバー側サポート
サーバーでは、SELECT ステートメントで FOR XML 句を使用することにより、テーブルやクエリ結果から XML データを生成できます。データ交換や Web サービス アプリケーションにとっては、これが理想的な処理になります。FOR XML の逆の処理を行うのは、OpenXML というリレーショナル行セット ジェネレータ関数です。この関数により XML データから値が抽出され、XPath 1.0 式を評価することによって、抽出されたデータが行セットの列に入力されます。OpenXML 関数は、受け取った XML データを細分化してテーブルに入力するアプリケーションや、T-SQL 言語を使用してクエリを行うアプリケーションによって使用されます。
・ クライアント側サポート
SQL Server 2000 のクライアント プログラミング サポートは、SQLXMLと呼ばれます。このテクノロジの中心となるのは XML ビューで、XML ビューにより、リレーショナル テーブルと XML スキーマの双方向マッピングが提供されます。後の Web リリースで XSD のサポートが追加されましたが、SQL Server 2000 では XDR スキーマのマッピングのみがサポートされています。XML ビューにより、XPath 1.0 のサブセットを使用したクエリを行えます。XML ビューでは、マッピングを使用して、パス式から基になるテーブル上の SQL クエリへの変換が行われ、クエリ結果が XML 結果にパッケージ化されます。
また、SQLXML により、XML テンプレートも作成できます。XML テンプレートでは、動的セクションを備えた XML ドキュメントを作成できます。XML ドキュメント内には、マッピング クエリにより FOR XML クエリや XPath 1.0 式を埋め込むことができます。XML テンプレートが実行されるときに、クエリ ブロックがクエリ結果に置き換えられます。このようにして、一部が静的コンテンツで、一部がデータ ドリブンの動的コンテンツである、XML ドキュメントを作成できます。
SQL Server 2000 では、SQLXML 機能にアクセスするための主な方法が 2 つあります。
・ SQLXMLOLEDB **プロバイダ:**SQLXMLOLEDB プロバイダは、ADO により Microsoft SQLXML 機能を公開する OLE DB プロバイダです。
・ HTTP アクセス:SQL Server 2000 の SQLXML 機能には、SQLXML ISAPI フィルタを使用して HTTP を経由することによってもアクセスできます。構成ツールを使用することにより、XML テンプレート、つまり HTTP 経由で XML ビュー上の FOR XML ステートメントと XPath 1.0 ステートメントを実行するために、着信要求を受け取るように Web サイトをセットアップできます。
XMLサポートでの制限事項
サーバー プログラミング プラットフォームとクライアント プログラミング プラットフォームにより、表形式のデータと XML データとの間のマッピングに基づいた、XML データの生成と使用のための豊富なサポートが提供されます。これにより、適切に構造化された XML データが適切に処理されます。SQLXML では、クエリ言語は XPath 1.0 のサブセットであり、いくつか制限事項があります。たとえば、descendant-or-self 軸 (//) はサポートされません (軸自体とその子孫軸)。その結果、特定のソリューション開発には制限が生じます。たとえば、XML ドキュメントの順序は保持されませんが、ドキュメント管理のようなアプリケーションにとっては、これは不可欠な要素です。しかも、再帰 XML スキーマがサポートされていません。このような制限事項にもかかわらず、クライアント SQLXML やサーバー XML の機能が、アプリケーション開発で幅広く使用されてきました。SQL Server 2005 では、これらの制限事項の多くに対処し、リレーショナル XML データの交換機能を拡張し、ネイティブ XML サポートを提供するようになりました。
SQL Server 2005での XML サポートの概要
ここでは、SQL Server 2005 に追加された新しい XML サポートについての概要を簡単に説明します。これら新しい XML サポートは、.NET Framework V2.0、および OLE DB などのネイティブ クライアント データ アクセスでのサポートによって補完されます。
XMLデータ型
XML データ モデルには、リレーショナル データ モデルにマップすることが実際には不可能ではないにしても、非常に困難であるという特徴があります。XML データには、再帰的になり得る階層構造があります。リレーショナル データベースでは、階層データが外部キー リレーションシップとしてモデル化されており、十分なサポートが提供されていません。ドキュメントの順序は XML インスタンスの固有のプロパティであり、クエリ結果で保持される必要があります。これは、順序が付けられないリレーショナル データとは対照的であり、順序を保持するために追加の順序列を設定する必要があります。クエリ中に結果の再組み立てを行うと、多くのテーブルに XML データを分解する現実的な XML スキーマにコストがかかります。
SQL Server 2005 では、XML というネイティブ データ型が導入されます。ユーザーは、リレーショナル列の他に、1 つ以上の XML 型の列を持つテーブルを作成できます。XML 変数やパラメータも使用できます。XML 値は、ドキュメントの順序や再帰構造などの、XML モデルの特性をより忠実にサポートするために、バイナリ ラージ オブジェクト (BLOB) を内部形式として使って格納されます。
SQL Server 2005 では、W3C XML スキーマをメタデータとして管理する方法として、XML スキーマ コレクションが提供されます。XML データ型を XML スキーマ コレクションと関連付けて、スキーマ制約が XML インスタンスに設定されるようにすることができます。XML データが XML スキーマ コレクションに関連付けられているときは、"型指定された XML" と呼ばれ、関連付けられていないときは、"型指定されていない XML" と呼ばれます。型指定された XML と型指定されていない XML の両方が 1 つのフレームワークに収められ、XML データ モデルが保持され、クエリ処理によって XML セマンティクスが設定されます。基になるリレーショナル インフラストラクチャが、この目的のために広範に使用されます。リレーショナル データと XML データとの間の相互運用がサポートされることによって、XML 機能がより広範に採用されるようになります。
XMLデータ型クエリとデータ変更
XML インスタンスは、T-SQL SELECT ステートメントを使用して取得できます。XML インスタンスのクエリや変更を行うために、XML データ型に関して 5 つの組み込みメソッドが提供されます。
XML データ型メソッドは、新しい W3C 標準言語である XQuery (現時点では最終審査請求中) を受け入れ、ナビゲーション言語である XPath 2.0 を含んでいます。また、サブツリーの追加や削除、スカラ値の更新などの、XML データの変更にも言語を使用できます。多数の関数、埋め込み XQuery およびデータ変更言語が組み合わされて、XML データの操作に対する豊富なサポートが提供されます。
XQuery 型システムは、W3C XML スキーマ型のシステムに合わせられています。大部分の SQL 型は、XQuery 型システムの型 (例、decimal) と互換性があります。扱いにくい型 (例、xs:duration) は内部形式で格納されており、XQuery 型システムとの互換性を維持するように適切に解釈されます。
コンパイルの段階で、XQuery 式やデータ変更ステートメントの型の正しさが静的に確認され、型指定された XML の場合には、型を推測するために XML スキーマが使用されます。タイプ セーフ性の違反によって実行時に式がエラーになる可能性がある場合、静的な型エラーが発生します。
XMLインデックス設定
クエリの実行により、実行時に各 XML インスタンスが処理されます。そのため、XML 値のサイズが大きかったり、またはテーブルの多くの行でクエリが評価される場合、負荷が高くなります。そのため、クエリの速度を向上するために、XML 列のインデックス設定のメカニズムが提供されます。
リレーショナル データのインデックス設定では、Bツリー が広範に使用されています。XML 列の XML プライマリ インデックスにより、すべてのタグ、値、およびその列の XML インスタンスのパスに、Bツリー インデックスが作成されます。これにより、XML データのクエリを効率的に評価でき、ドキュメントの順序やドキュメント構造の保持したまま、Bツリー から XML 結果の再組み立てを行えます。
XML セカンダリ インデックスを XML 列に作成することにより、一般的に行われるクエリとは異なるクラスの速度に向上できます。セカンダリ インデックスには、パス ベースのクエリの PATH インデックス、プロパティ バッグのシナリオでの PROPERTY インデックス、値ベースのクエリの VALUE インデックスなどがあります。
XMLスキーマ処理
XML 列、変数、およびパラメータには、XML スキーマのコレクションに応じて、オプションで型を指定できます。XML スキーマのコレクションは、(たとえば、<xs:import> を使用することによって) 相互に関連させたり、関連させないようにすることができます。それぞれの型指定された XML インスタンスにより、準拠している XML スキーマ コレクションから、対象となる名前空間が指定されます。データの割り当てや変更中に、データベース エンジンにより、XML スキーマに応じてインスタンスが検証されます。
ストレージの最適化やクエリの最適化では、XML スキーマ情報が使用されます。型指定された XML インスタンスには、内部で型指定された値、つまり、XML インデックスのバイナリ表現が含まれます。これにより、型指定された XML データを効率的に処理できます。
リレーショナル データと XML データの統合
ユーザーは、リレーショナル データと XML データの両方を同じデータベース内に格納できます。簡単に言うと、データベース エンジンにより、リレーショナル データ モデルの他に、XML データ モデルの処理を行う方法が認識されます。リレーショナル データや SQL アプリケーションは、SQL Server 2005 にアップグレードしても、正しく動作し続けます。ファイルやテキスト列またはイメージ列にある XML データは、サーバーで XML データ型列に移動できます。XML データ型メソッドを使用すると、XML 列にはインデックスを設定でき、クエリや変更が行えます。
データベースにより、記憶域エンジンや XML 処理のクエリ プロセッサなどの、既存のリレーショナル インフラストラクチャやエンジン コンポーネントが活用されます。たとえば、XML インデックスにより Bツリー が作成されるので、プラン表示出力にクエリ プランを表示できます。バックアップと復元やレプリケーションなどのデータ管理機能はリレーショナル フレームワークに統合され、XML データでも使用できます。同様に、データベースのミラーリングやスナップショット分離などの新しいデータ管理機能が XML データ型と連携され、シームレスな操作感が提供されます。
構造化されたデータは、テーブルやリレーショナル列に格納される必要があります。アプリケーションが厳密なクエリを実行し、データを変更する必要があるときは、XML を使用して半構造化され、マークアップされたデータにとっては、XML データ型を使用することが最適な選択肢になります。
FOR XMLと OpenXML の機能拡張
既存の FOR XML 機能が、いくつかの点で機能拡張されました。FOR XML は、XML データ型のインスタンスや [n]varchar(max) などのその他の新しい SQL 型で機能します。
新しい TYPE ディレクティブにより、XML 列、変数、またはパラメータに割り当て可能な XML データ型インスタンスが生成されます。または XML データ型メソッドを使用してクエリが行われます。これにより、SELECT ... FOR XML TYPE ステートメントの入れ子が可能になります。
PATH モードにより、列の値を表示する XML ツリー内のパスをユーザーが指定でき、前述の入れ子と組み合わせることにより、FOR XML EXPLICIT よりも記述が簡単になります。
ELEMENTS と共に使用されるディレクティブ XSINIL により、属性 xsi:nil="true" を持つ要素に NULL がマップされます。また、新しい ROOT ディレクティブにより、ルート ノードが FOR XML のすべてのモードで指定されます。新しい XMLSCHEMA ディレクティブにより、XSD インライン スキーマが生成されます。
OpenXML の機能拡張には、sp_preparedocument での XML データ型の受け取り、行セットでの XML 列や新しい SQL 型列の生成などがあります。
XMLデータ型へのクライアント アクセス
クライアントは、いくつかの方法でサーバーの XML データにアクセスできます。ODBC や OLE DB を使用したネイティブ SQL クライアント アクセスにより、Unicode 文字列として XML データ型が提供されます。また、OLE DB により、ストリーミング Unicode データ用に、XML データ型への ISequentialStream アクセスが提供されます。
.NET Framework V2.0 での ADO.NET 経由のマネージ アクセスにより、SqlXml という新しいクラスとして、XML データが配信されます。返された XML データを読み取るために XmlReader インスタンスを返す、CreateReader() というメソッドがサポートされます。同様に、DataSet により、XML データ型のインスタンスを中間層の列に読み込み、XML ドキュメントとして編集し、SQL Server に戻して保存することができます。これらの両方により、中間層での操作で XML 列を取得するために、SQL クエリをサーバーに発行できるようになります。
SQL Server 2005 での HTTP エンドポイントへの SOAP 直接アクセス機能を、XML データのクエリ、取得、および変更に使用できます。
ネイティブおよびマネージ クライアント テクノロジの両方により、XML 列の型を指定する XML スキーマ コレクションを取得するための新しいインターフェイスが提供されます。
XMLストレージのきっかけとなるシナリオ
XML データはさらに広がっていく傾向にあります。顧客データがその代表的なものですが、これはデータを記述する XML スキーマを備えたものも、備えていないものもあります。XML データと XML スキーマの両方が、一緒に管理される必要があります。現実のアプリケーションの XML スキーマは複雑になることが多く、そのような XML スキーマからテーブルや列へのマッピングは複雑な作業になります。XML スキーマが変更されたり、新しい XML スキーマがシステムに追加されたとき、そのようなマッピングを長期間管理することは困難です。多くの場合、XML データは、データベース サーバーのファイル システムまたはテキスト列に格納されます。テキスト列は、レプリケーションやバックアップと復元などのデータの管理を行う際には有益ですが、データの XML 構造に基づいたクエリはサポートされません。ネイティブ XML サポートにより、XML を使用するアプリケーションの開発を迅速に行えるようになります。
カスタム プロパティの管理
ユーザー インターフェイス ソフトウェアのようなアプリケーションでは、固定的なプロパティのセットからユーザーが選択できるものがあります。ユーザーが独自のプロパティを定義できるアプリケーションもあります。そのようなカスタム プロパティが XML 形式で格納されていると、プロパティの管理を適切に行うことができます。アプリケーションはスカラ プロパティよりも多くのことをサポートできます。
・ 複数の電話番号など、オブジェクトで複数値を備えたプロパティをサポートできます。
・ 複雑なプロパティをサポートできます。たとえば、ドキュメントの執筆者のプロパティを執筆者の連絡先情報にするような場合などです。
オブジェクト プロパティは XML データ型列に格納でき、効率的にクエリ処理を行うためにインデックスを設定できます。
データ交換とワークフロー
XML により、プラットフォームに依存しない方法で、アプリケーション間でデータを交換できます。交換するデータを、XML マークアップを備えたメッセージとしてモデル化できます。XML メッセージは、常に細分して生成するのではなく、XML 形式で格納することが賢明です。これは、データフローの要件にうまく適合します。ワークフローの段階に達する XML メッセージにより、現在の状態が伝わります。各メッセージが処理され、XML コンテンツに進行状況 (状態変更など) が記録され、ワークフロー処理の次の段階に XML データが転送されます。メッセージは異なる型であったり、半構造化され、メッセージに関連付けられたさまざまな XML スキーマを備えている可能性があります。したがって、メッセージをテーブルにマッピングすることは、常に、簡単な作業になるわけではありません。
XML ベースの標準は、財務データや地理空間データのように、さまざまな垂直領域を対象として生まれました。このような標準によって、どのインスタンスに基づいてデータにクエリが行われ、更新されるのかというデータの構造が説明されます。実際のデータはバイナリ形式でも、XML データによってデータに関するメタデータ情報が提供されることがよくあります。
単純な例では、入力パラメータのテーブルをストアド プロシージャまたは関数に渡すために、アプリケーションによりデータが XML に変換され、XML データ型パラメータとして渡されます。ストアド プロシージャまたは関数内では、XML パラメータから行セットが再生成されます。
ドキュメント管理
コール センターが、患者の記録や会話を XML ドキュメントとして管理しているとします。コール センターでは、患者から電話がかかってきたときに、以前の会話を呼び出して、かかってきた電話の状況を把握したいと考えています。これは、XML マークアップをクエリすることにより可能であり、アプリケーションで利用できます。さらに、以前の会話の詳細を取得したり、現在の会話を記録することが容易になります。
電子メールのようなドキュメントは、本質的に半構造化されています。XML マークアップを備えたドキュメントは、たとえば、Office 2003 により作成が容易になります。このような XML ドキュメントは XML 列に格納でき、インデックス設定、クエリ、および更新が可能になります。このように、ネイティブ XML サポートを使用すると、開発者はより多くのことを行えるようになります。
SQL Server 2005でのサーバー側の XML 処理
SQL Server 2005 のサポートは、リレーショナル データと XML データを格納できる 1 つのデータベースを提供することで成り立っています。
XMLデータ型
通常の CREATE TABLE ステートメントを使用して、XML 列を備えたテーブルを作成できます。その後、XML 列に特別な方法でインデックスを設定できます。
型指定されていない XML
SQL Server 2005 の XML データ型により、ISO SQL-2003 標準の XML データ型が実装されます。したがって、整形式の XML 1.0 ドキュメントのみでなく、テキスト ノードや任意の数の最上位レベル要素を持つ、いわゆる XML コンテンツ フラグメントも格納できます。データが整形式かどうかの確認が行われます。XML データ型が XML スキーマに連結されている必要はありませんが、整形式でないデータは却下されます。
型指定されていない XML 列は、スキーマが既知の "演繹" でない場合に有用なので、マッピングベースのソリューションは不可能です。また、型指定されていない XML 列は、スキーマが既知でもリレーショナル データ モデルへのマッピングが非常に複雑で管理が困難である場合、または複数のスキーマが存在し、外部要件に基づいてデータに遅延バインディングされる場合にも役に立ちます。
例: テーブル内の型指定されていない XML 列
次のステートメントを実行すると、整数型の主キー "pk" と型指定されていない XML 列 "xCol" を持つ、"docs" というテーブルが作成されます。
CREATE TABLE docs (pk INT PRIMARY KEY, xCol XML not null)
また、複数の XML 列、またはリレーショナル列を持つテーブルも作成できます。この場合、リレーショナル列は主キーを持つ場合も、持たない場合もあります。
型指定された XML
XML データを説明する XML スキーマが XML スキーマ コレクションにある場合、XML スキーマ コレクションを XML 列に関連付けて、"型指定された" XML を生成できます。データを検証したり、クエリやデータ変更ステートメントのコンパイル中に、型指定されていない XML よりも正確な型の確認を実行したり、ストレージやクエリ処理を最適化するために、XML スキーマが使用されます。
型指定された XML 列、パラメータ、および変数には、XML ドキュメントまたはコンテンツを格納できます。これは、(DOCUMENT または CONTENT を個別に、または 既定として CONTENT を) 宣言時にオプションとして指定できます。さらに、XML スキーマのコレクションを指定する必要があります。各 XML インスタンスに 1 つだけ最上位要素がある場合は DOCUMENT を指定し、それ以外の場合は CONTENT を使用します。単一の最上位要素があるかどうかを推測するために、型確認の際に、クエリ コンパイラによって DOCUMENT フラグが使用されます。
例: テーブル内の型指定された XML 列
XML 列、変数、およびパラメータは、XML スキーマのコレクションにバインドできます (詳細および例については、この資料の後半の「XML スキーマ処理」を参照してください)。myCollection が前述のコレクションを表すとします。以下のステートメントを実行すると、myCollection を使用して Document 型が指定された XML 列を持つ、テーブル XmlCatalog が作成されます。また、XML ドキュメントだけでなく XML フラグメントを受け取るために、型指定された XML 列が指定されることもあります。
CREATE TABLE XmlCatalog (
ID INT PRIMARY KEY,
Document XML(CONTENT myCollection))
・ XMLデータ型の列の制約
XML 列の型指定の他に、型指定された XML データ型の列や型指定されていない XML データ型の列上で、リレーショナル (列または行) 制約を使用できます。大部分の SQL 制約は XML 列にも適用されますが、XML データ型インスタンスは比較できないので、一意制約、主キー制約、および外部キー制約は例外になります。このように、XML 列に対して NULL 値を許容したり、または NULL 値を許容しないように指定できます。また、既定値を提供したり、列で CHECK 制約を定義できます。たとえば、格納された XML インスタンスが XML スキーマに準拠していることを検証するために、型指定されていない XML 列に CHECK 制約を設定できます。
次の条件を満たす場合、制約を適用します。
・ XML スキーマでビジネス ルールを表現できない場合。たとえば、花屋の配送先住所は店舗から 50 マイル以内である必要がある場合、これを XML 列に制約として設定できます。制約には、XML データ型のメソッドが必要になる場合があります。
・ テーブルの別の列 (XML 列かどうかは問いません) が制約に関与する場合。たとえば、XML インスタンス内の顧客 ID (/Customer/@CustId) を、整数型の列 CustomerID の値に一致させるように制約するような場合です。
例: XML 列の制約
<book> の <author> の <last-name> が、<author> の <first-name> と異なるようにするために、次の CHECK 制約を指定できます。
CREATE TABLE docs (pk INT PRIMARY KEY,
xCol XML not null
CONSTRAINT CK_name CHECK
(xCol.exist('/book/author[first-name = last-name]') = 0))
・ テキスト エンコーディング
SQL Server 2005 では、XML データを Unicode (UTF-16) で格納します。サーバーから取得したXML データは、UTF-16 エンコーディングでも出力されます。異なるエンコーディングが必要な場合、データを取得した後に、キャストすることによって、または中間層で、必要な変換を実行する必要があります。たとえば、サーバー上で XML データを varchar 型にキャストできます。その際、データベース エンジンでは、varchar の照合によって判断されたエンコーディングを使用して、XML データがシリアル化されます。
XMLデータの格納
XML 列、パラメータ、または変数に対して、複数の方法で XML 値を指定できます。
・ XML データ型に暗黙的に変換される、文字またはバイナリの SQL 型として。
・ ファイルのコンテンツとして。
・ XML データ型インスタンスを生成する、type ディレクティブを持つ XML 公開メカニズム FOR XML の出力として。
指定された値が整形式であるかどうかが確認され、XML ドキュメントと XML フラグメントの両方が格納可能になります。整形式の確認がエラーになった場合、適切なエラー メッセージが表示され、格納が拒否されます。
型指定された XML 列の場合は、指定された値が XML スキーマに準拠しているかどうかが確認されます。XML スキーマは、XML 列の型指定を行う XML スキーマ コレクションと共に登録されます。この検証に失敗すると、XML インスタンスは拒否されます。さらに、型指定された XML 列の DOCUMENT フラグにより、受け取られる値は XML ドキュメントにのみに制限されます。それに対して、CONTENT フラグでは、指定される XML ドキュメントとコンテンツの両方を受け取ることができます。
例: 型指定されていない XML 列へのデータの挿入
次のステートメントを実行すると、整数列 pk に値 1 を持ち、XML 列に<book> インスタンスを持つテーブル docs に、新しい行が挿入されます。文字列で指定される <book> データは、暗黙に XML データ型に変換され、挿入時に整形式かどうかが確認されます。
INSERT INTO docs VALUES (1,
'<book genre="security" publicationdate="2002" ISBN="0-7356-1588-2">
<title>Writing Secure Code</title>
<author>
<first-name>Michael</first-name>
<last-name>Howard</last-name>
</author>
<author>
<first-name>David</first-name>
<last-name>LeBlanc</last-name>
</author>
<price>39.99</price>
</book>')
例: ファイルから、型指定されていない XML 列へのデータの挿入
以下に示す INSERT ステートメントでは、OPENROWSET を使用して BLOB として、ファイル C:\temp\xmlfile.xml のコンテンツを読み取ります。主キーに値 10 を持ち、XML 列 xCol に BLOB を持つテーブル docs に、新しい行が挿入されます。ファイル コンテンツが XML 列に割り当てられると、整形式の確認が開始されます。
INSERT INTO docs
SELECT 10, xCol
FROM (SELECT * FROM OPENROWSET
(BULK 'C:\temp\xmlfile.xml',
SINGLE_BLOB) AS xCol) AS R(xCol)
例: 型指定された XML 列へのデータの挿入
型を指定するために使用されている XML スキーマの対象となる名前空間を指定するために、型指定された XML 列では XML インスタンス データが必要になります (名前空間は空になる可能性があります)。以下に示す例では、名前空間宣言 xmlns=http://myDVD によってこれが行われています。
INSERT XmlCatalog VALUES(2,
'<?xml version="1.0"?>
<dvdstore xmlns="http://myDVD">
<dvd genre="Comedy" releasedate="2003">
<title>My Big Fat Greek Wedding</title>
<price>19.99</price>
</dvd>
</dvdstore>')
例: TYPE ディレクティブを持つ FOR XML を使用して生成された XML データの格納
XML データ型インスタンスとして結果を生成するために、TYPE ディレクティブにより FOR XML が機能強化されました。結果の XML は、XML 列、変数、またはパラメータに代入できます。次のステートメントでは、FOR XML TYPE を使用して生成された XML インスタンスが、XML データ型の変数 @xVar に代入されます。変数には、XML データ型メソッドを使用してクエリできます。
DECLARE @xVar XML
SET @xVar = (SELECT * FROM docs FOR XML AUTO,TYPE)
・ ストレージの表現
XML データ型インスタンスはストリーミング可能な内部のバイナリ表現で格納され、効率的な解析のために最適化されます。整数値にタグがマップされ、マップされた値が内部表現で格納されます。また、これにより、一部のデータが圧縮されます。
型指定されていない XML 列の場合は、ノード値が Unicode (UTF-16) 文字列として格納されます。したがって、操作を実行するためには、実行時に型変換が必要になります。たとえば、/book/price > 9.99 という述語を評価するために、書籍の価格の値が小数値に変換されます。それに対して、型指定された XML 列の場合は、XML スキーマで指定した型に値がエンコードされます。このためデータの解析をより効率的に行えるようになり、実行時の変換を回避できます。
格納されるバイナリ形式は、XML インスタンスごとに 2 GB に制限されますが、この容量で大部分の XML データを収容できます。さらに、XML 階層の深さは 128 レベルに制限されます。
XML データの InfoSet コンテンツが保持されます。これは、次の情報が保持されないので、テキスト XML の正確なコピーにはならないことがあります。意味のない空白、属性の順序、名前空間プレフィックス、および XML 宣言。
データ モデリングの考慮事項
多くの場合、リレーショナル列と XML データ型の列の組み合わせが、データ モデリングに適しています。XML データから取り出した値の中には、リレーショナル列に保存できるものもありますが、それ以外の値や XML 値全体は、XML 列に保存されます。これにより、パフォーマンスが向上し、特性がロックされます。
XML データ内の値は、同じテーブルの単一値 (すなわち、単一の値を持つプロパティ) の計算列に昇格できます。複数値を持つプロパティでは、プロパティ用に別のテーブルが必要になります。これは、トリガを使用して生成および管理する必要があります。クエリは、直接プロパティ テーブルに対して記述される必要があります。
XML 列に格納されている XML データの精度は、特性のロックや更新にとって重要になります。SQL Server では、XML データおよび非 XML データの両方に対して、同じロック メカニズムが使用されます。大まかな精度の場合、更新のために大きな XML インスタンスをロックすると、複数ユーザーのシナリオではスループット低下につながります。一方、あまり細かく分解すると、オブジェクトのカプセル化が失われ、再組み立てコストが発生します。
XMLデータのクエリと変更
XML 列に格納された XML インスタンスのクエリでは、列のバイナリ XML データの解析が必要になります。バイナリ XML データの解析は、テキスト形式の XML データの解析よりも高速に行うことができます。XML インデックス設定により再解析が回避されます。これは、「XML データへのインデックスの設定」で説明しています。
XMLデータ型のメソッド
必要な場合は XML 値全体を取得できます。また、XML インスタンスの一部を取得することもできます。以下の 4 つの XML データ型メソッドを使用すると、これが可能になります。query()、value()、exist() および nodes() では、XQuery 式を引数として受け取ります。5 番目のメソッドである modify() により、XML データの変更が可能になり、XML データ変更ステートメントを入力として受け取ります。
XML インスタンスの一部を抽出するには、query() メソッドが有用です。XQuery 式により、XML ノードのリストが評価されます。これらの各ノードのルートにあるサブツリーが、ドキュメントの順序に従って返されます。結果の型は、型指定されていない XML になります。
value() メソッドにより、XML インスタンスからスカラ値が抽出されます。XQuery 式によって評価されるノードの値が返されます。この値は、value() メソッドの2 番目の引数として指定された、T-SQL 型に変換されます。
XML インスタンスの存在を確認するために、exist() メソッドを使用します。XQuery 式によって NULL 以外のノード リストに評価された場合は 1 が返され、それ以外の場合は 0 が返されます。
nodes() メソッドにより、特別な XML データ型のインスタンスが生成されます。そのそれぞれには、XQuery 式が評価する、異なるノードに対するコンテキストのセットがあります。特別な XML データ型では、query()、value()、nodes() および exist() メソッドがサポートされ、これらのメソッドは count(*) 集計および NULL 確認で使用できます。それ以外で使用すると、エラーになります。
modify() メソッドでは、XML インスタンスの一部分の変更が許可されています。たとえば、サブツリーの追加や削除、または、たとえば書籍の価格を 9.99 から 39.99 にするようなスカラ値の置き換えが可能です。
例: query() メソッドの使用
ID が 123 である <doc> 要素の下にある <section> 要素を抽出する、テーブル docs の XML 列 xCol での以下のクエリを考えてみます。また、クエリにより、整数型の主キー列からも値が取得されます。SELECT リストの query() メソッドは、<section> 要素のシーケンスを生成して、テーブルの行ごとに評価されます。これはサブツリーと合わせて、ドキュメントの順序で取得されます。ID 123 を持ち <doc> 要素がない、またはそれ以下に <section> 要素がない XML インスタンスでは、結果が返されません。すなわち、query() メソッドの戻り値は NULL になります。
SELECT pk, xCol.query('/doc[@id = 123]//section')
FROM docs
NULL の戻り値は、外側の SELECT ステートメントでフィルタ処理できます。または、次の例で示すように exist() **** メソッドを使用できます。
例: exist() メソッドの使用
テーブル docs の XML 列 xCol で、query() メソッドと exist() メソッドを含む以下のクエリを考えてみます。exist() メソッドにより、値 123 の id という属性を持つ最上位レベルの <doc> 要素の存在が確認され、パス式 /doc[@id = 123] が評価されます。それぞれの当該行では、SELECT 句の query() メソッドが評価されます。この例では、query() メソッドにより、<doc> 要素の下で <section> 要素のシーケンスが生じます。exist() メソッドで 0 が返されたすべての行がスキップされます。
SELECT xCol.query('/doc[@id = 123]//section')
FROM docs
WHERE xCol.exist ('/doc[@id = 123]') = 1
例: value() メソッドの使用
次のクエリにより、value() メソッドを使用して、ドキュメントの 3 番目のセクションの見出しが Unicode 文字列として抽出されます。value() メソッド の 2 番目の引数として、結果の SQL 型 nvarchar(max) が指定されます。XQuery 関数 data() により、<heading> ノードからスカラ値が抽出されます。
SELECT xCol.value(
'data((/doc//section[@num = 3]/heading)[1])',
'nvarchar(max)')
FROM docs
・ XQuery言語
ファイル システム、Webサービスまたは構成ファイルに格納される Office ドキュメントには、多数の XML のソースがあります。実際は、XML 形式で、または仮想 XML ドキュメントとして、データが徐々に生成されていきます。このデータの増加量に対応するために、強力なクエリ言語 XQuery が考案されました。http://www.w3.org/TR/xqueryの XQuery 言語仕様に、XQuery を使用する理由が以下のように説明されています。
・ XML の構造を知的に使用するクエリ言語により、XML に物理的に格納されていようと、またはミドルウェアによって XML として表示されていようと、すべての種類のデータ間でクエリを表現できます。この仕様では、多くの型の XML データ ソースで広く適用可能になるようにデザインされた、XQuery というクエリ言語が説明されています。
・ XQuery は、「W3C XML Query Working Group XML Query 1.0 Requirements」によって特定された要件と「XML Query Use Cases」のユース ケースをを満たすようにデザインされています。XQuery は、クエリが簡潔で容易に理解できる言語になるようにデザインされています。また、データベースとドキュメントの両方を含む、XML 情報ソースの広い範囲に対してクエリを行うように、柔軟にデザインされています。
・ XQuery は次の文章のように要約することができます。「XQuery 言語は XML に対するもので、SQL 言語はリレーショナル データベースに対するものです。」
T-SQL に埋め込まれる http://www.w3.org/TR/xquery/ の XQuery のサブセットは、XML データ型のクエリ用にサポートされる言語です。この言語は、Microsoft を含む、すべての主要なデータベース ベンダが参加している Worldwide Web Consortium (W3C) によって開発されています (現時点では最終審査請求中)。Microsoft の実装は、XQuery の2003 年 11 月のドラフトに合わせられています。
XQuery には、ナビゲーション言語として XPath 2.0 が含まれます。SQL Server 2005 での XQuery の実装により、ノード (for)、ノード確認 (where)、戻り値 (return)、および並べ替え (order by) での反復のための構造が提供されます。また、クエリ中にデータを再形成するための要素構造も提供されます。
SQL Server 2005 では、XML データ型のデータ変更 (DML) のための、言語構成も提供されます (詳細については、以下の「データの変更」を参照してください)。次の例では、XML データ型での XQuery の使用法を示しています。
例: XQuery での豊富な言語構成の使用
以下のクエリでは、組み合わせて使用されるいくつかの XQuery 言語構成を示しています。id 123 を持つドキュメントから、新しいタグ <topic> で囲まれた、セクション番号 3 以上を持つセクションの見出しが返されます。
SELECT pk, xCol.query('
for $s in /doc[@id = 123]//section
where $s/@num >= 3
return <topic>{data($s/heading)}</topic>')
FROM docs
id 123 を持つ <doc> 要素の下のすべての <section> 要素で、"for" が繰り返されます。また、それぞれの <section> が変数 $s にバインドされます。"where" によって、セクション番号 (<section> 要素の @num 属性) が 3 以上であることが確認されます。クエリにより、<topic> という構成要素で囲まれたドキュメントの順序で、セクション <heading> の値が返されます。
クエリのコンパイルと実行
SQL パーサーによって、SQL ステートメントが解析されます。XQuery 式が見つかると、XQuery コンパイラに移動し、XQuery 式がコンパイルされます。これにより、全体的なクエリのクエリ ツリーに移植されたクエリ ツリーが作成されます。
全体的なクエリ ツリーでクエリの最適化が行われ、コスト ベースの推定に基づいて選定される、物理的なクエリ プランが作成されます。プラン表示出力の大部分はリレーショナル演算子ですが、XML 処理の UDX などの新しい演算子も一部表示されます。
クエリの実行は、他のリレーショナル フレームワークと同様に組指向です。WHERE 句は、テーブル docs の各行で評価されます。これには、XML データ型メソッドを評価するための実行時の XML blob 解析が含まれます。条件が満たされた場合、行がロックされ、その行で SELECT 句が評価されます。query() メソッドの XML データ型として結果が作成され、value() メソッドに指定した対象の型に変換されます。
それに対して、行が WHERE 句の条件を満たさない場合、その行はスキップされ、次の行が実行されます。
XMLデータの変更
SQL Server 2005 では、XQuery への拡張としてデータ変更の構成が提供されます。指定したノードの前後、または左端の子または右端の子としてサブツリーを挿入できます。さらに、サブツリーを親ノードに挿入できます。その場合、挿入したサブツリーは、親の右端の子になります。属性、要素、およびテキスト ノードの挿入は、すべてサポートされます。
サブツリーの削除もサポートされます。この場合、XML インスタンスからサブツリー全体が削除されます。
スカラ値は新しいスカラ値に置き換え可能です。
例: XML インスタンスへのサブツリーの挿入
この例では、番号が 1 である <section> 要素の右側に、新しい <section> 要素を挿入するために、modify() メソッドを使用する例を示しています。
UPDATE docs SET xCol.modify('
insert
<section num="2">
<heading>Background</heading>
</section>
after (/doc/section[@num=1])[1]')
例: この書籍の価格を $49.99 に更新
次の更新ステートメントによって、ISBN が 1-8610-0311-0 の書籍の <price> が $49.99 に置き換えられます。XML インスタンスは XML スキーマ http://myBooks、つまり XML データ変更ステートメントの名前空間宣言で型が指定されています。
UPDATE XmlCatalog
SET Document.modify ('
default namespace = "http://myBooks"
replace value of (/bookstore/book[@ISBN=
"1-8610-0311-0"]/price)[1] with 49.99')
型の確認と静的エラー
XQuery では型の確認が導入されています。コンパイルの段階では、XQuery 式とデータ変更ステートメントの型の正確さが静的に確認され、型指定された XML の場合には、型の推測のために XML スキーマが使用されます。タイプ セーフ性違反によって実行時に式がエラーになる可能性がある場合、静的な型エラーが発生します。以下は静的エラーの例です。整数への文字列の追加、操作によって単一値が予測されている場所での値のシーケンスの受け取り、型指定されたデータが存在しないノードへのクエリなどがあります。適切な型に明示的にキャストすることにより、型の不一致が原因で発生する静的エラーを回避できます。XQuery の実行時エラーは空のシーケンスに変換されます。
実行時にシングルトンが保証されているかどうかをコンパイラが判断できない場合、シングルトンを必要とする場所の手順、関数パラメータ、および演算子 (たとえば、eq) は、エラーを返します。型が指定されていないデータでは、問題が発生することが多くなります。たとえば、属性の照合には 1 つの親要素が必要になります。この場合は、1 つの親ノードを序数選択することが適切です。
例: value() メソッドでの型の確認
value() メソッドでは最初の引数としてシングルトン ノードが期待されるので、以下の型指定されていない XML 列でのクエリでは、//author/last-name での序数指定が必要になります。それがないと、ある <last-name> ノードが実行時に発生するかどうかを、コンパイラが判断できません。
SELECT xCol.value('(//author/last-name)[1]', 'nvarchar(50)') LastName
FROM docs
属性値を抽出するための node() と value() の組み合わせの評価では、次の例で示すとおり、序数指定を必要としない場合があります。
例: 既知のシングルトン
以下に示す nodes() メソッドでは、<book> 要素ごとに別の行が生成されます。<book> ノードで評価された value() メソッドにより、@genre の値が抽出されます。これが属性となり、これはシングルトンです。
SELECT nref.value('@genre', 'varchar(max)') LastName
FROM docs CROSS APPLY xCol.nodes('//book') AS R(nref)
リレーショナル データと XML データにまたがるクエリ
リレーショナル データ型と XML データ型を組み合わせた列にデータがある場合、リレーショナル データと XML データの処理を結合するクエリを記述する必要があるかもしれません。TYPE ディレクティブを持つ FOR XML を使用してリレーショナル列と XML 列のデータを XML データ型のインスタンスに変換し、それに対して XQuery でクエリを実行できます。逆に、以下の「XML データからの行セットの生成」で示すように、XML 値から行セットを生成し、T-SQL を使用してクエリを行うこともできます。
リレーショナル データ型と XML データ型にまたがるクエリを記述する、より便利で効率的な方法としては、SQL 変数または XQuery 内の列または XML データ変更式の値を使用する方法があります。
・ sql:variable() を使用して、XQuery または XML DML 式の SQL 変数の値を適用します。
・ sql:column() により、XQuery または XML DML コンテキストのリレーショナル列の値を使用します。
以下の例で示すように、このアプローチによってアプリケーションがクエリをパラメータ化できます。Sql:column() は似たような方法で使用されますが、Sql:variable() よりも便利です。コストに基づくクエリ オプティマイザによって決定されたとおりに効率を上げるために、列にインデックスを使用できます。さらに、計算列も使用できます。
XML データ型やユーザー定義型は、sql:variable() や sql:column() と一緒には使用できません。
例: sql:variable() を使用したリレーショナル データと XML データにまたがるクエリ
このクエリでは、SQL 変数 @isbn を使用して、<book> 要素の ISBN が渡されます。定数を使用する代わりに、sql:variable() によって ISBN の値が提供され、クエリを使用して、ISBN が 0-7356-1588-2 であるものだけでなく、どのような ISBN でも検索できます。
DECLARE @isbn varchar(20)
SET @isbn = '0-7356-1588-2'
SELECT xCol
FROM docs
WHERE xCol.exist ('/book[@ISBN = sql:variable("@isbn")]') = 1
・ XMLデータからの行セットの生成
カスタム プロパティ管理とデータ交換のシナリオでは、アプリケーションによって XML データの一部が行セットにマップされることがよくあります。たとえば、入力パラメータのテーブルをストアド プロシージャまたは関数に渡すために、アプリケーションによってデータが XML に変換され、XML データ型パラメータとして渡されます。ストアド プロシージャまたは関数内では、XML パラメータから行セットが生成されます。
この目的のために、SQL Server 2005 により OpenXML() が提供されます。これは、行セットのリレーショナル スキーマと、XML インスタンス内の値が行セットの列にマップされる方法を指定することによって、XML インスタンスから行セットを生成するための機能です。
または、nodes() メソッドを使用して、XML インスタンス内にノード コンテキストを生成できます。また、value()、query()、exist() および nodes() メソッドのノード コンテキストを使用して、目的の行セットを生成できます。nodes() メソッドは XQuery 式を受け取り、XML 列のそれぞれの XML インスタンスで評価され、XML インデックスが効率的に使用されます。次の例では、行セットを生成するために nodes() メソッドを使用する方法について説明しています。
例: XML インスタンスからのプロパティの抽出
FirstName と LastName の 2 つの列からなる行セットで、名前が "David" ではない作者の名前と姓を抽出するとします。この処理は、nodes() および value() メソッドを使用して、次のように実現できます。
SELECT nref.value('first-name[1]', 'nvarchar(50)') FirstName,
nref.value('last-name[1]', 'nvarchar(50)') LastName
FROM docs CROSS APPLY xCol.nodes('//author') AS R(nref)
WHERE nref.exist('.[first-name != "David"]') = 1
この例では、nodes('//author') によって、XML インスタンスごとに、<author> 要素を参照する行セットが生成されます。作者の名前と姓は、それらの参照に関連する value() メソッドを評価することにより取得されます。優れたパフォーマンスを実現するために、XML 列にはインデックスが設定されている必要があります。これを、次のセクションで説明します。
XMLデータのインデックスの設定
XML データは内部バイナリ形式で格納されており、ストレージ内で 2 GB まで格納できます。各クエリでは、テーブルの各行で、実行時に 1 回以上 XML blob が解析されます。このため、クエリ処理が遅くなります。通常、ワークロードでクエリを実行する場合、XML 列にインデックスを設定すると便利です。ただし、データ変更時の XML インデックスの保守コストを考慮する必要があります。
型指定された XML 列と型指定されていない XML 列上で、新しい DDL ステートメントを使用して、XML インデックスが作成されます。これにより、列のすべての XML インスタンスに対する Bツリー が作成されます。XML 列の最初のインデックスは、"XML プライマリ インデックス" になります。これを使用すると、次に説明するように、3 種類の XML セカンダリ インデックスが XML 列でサポートされ、一般的なクエリの速度が向上されます。
XMLプライマリ インデックス
XML プライマリ インデックスでは、基になるテーブル (すなわち、XML 列が定義されるテーブル) の主キーにクラスタ化インデックスが必要になります。XML ノードの Infoset 項目のサブセットに、Bツリー が作成されます。Bツリー の列は、要素名、属性名、ノード値、ノードの種類などのタグを表します。他の列により、XML データ内でのドキュメントの順序や構造がキャプチャされ、パス式の効率的な評価のために XML インスタンスのルートから各ノードへのパスがキャプチャされます。基になるテーブルの主キーは、インデックス行と基になるテーブル行が相互関連するように、XML プライマリ インデックスにコピーされます。
XML スキーマで提供されるタグと型の名前は、整数値にマップされます。マップされた値は Bツリー に格納され、ストレージが最適化されます。インデックスのパス列には、マップされた値が逆の順序で、すなわちノードから XML インスタンスのルートへの順序で連結されて格納されます。逆表記により、(たとえば //author/last-name のようなパス式で) パスのサフィックスが既知であれば、パス値を一致させることができます。
基になるテーブルがパーティション分割されている場合、XML プライマリ インデックスも同じ方法でパーティション分割されます。すなわち、同じパーティション分割関数やパーティション分割手法が使用されます。
XML 列から完全な XML インスタンスが取得されます (SELECT * FROM docs または SELECT xCol FROM docs)。XML データ型メソッドに関係するクエリでは、XML プライマリ インデックスが使用され、インデックス自体からスカラ値または XML サブツリーが返されます。
例: XML プライマリ インデックスの作成
次のステートメントを実行すると、テーブル docs の XML 列 xCol に、idx_xCol というXML インデックスが作成されます。
CREATE PRIMARY XML INDEX idx_xCol on docs (xCol)
・ XMLセカンダリ インデックス
XML プライマリ インデックスが作成されると、ワークロード内のさまざまなクラスのクエリの速度を向上するために、XML セカンダリ インデックスを作成できます。3 種類の XML セカンダリ インデックス、PATH、PROPERTY、および VALUE は、パスベースのクエリ、カスタム プロパティ管理のシナリオ、および値ベースのクエリにそれぞれの利点があります。
・ PATH インデックスにより、XML プライマリ インデックスの列 (パス、値) に Bツリー が構築されます。パス式からパスの値が計算され、もしあれば、ノードの値も使用されます。PATH インデックスを導くフィールドが既知であれば、PATH インデックスを求めることにより、パス式の評価速度が向上します。最も一般的なケースは、SELECT ステートメントの WHERE 句の XML 列で、exist() メソッドを使用することです。
・ PROPERTY インデックスにより、XML プライマリ インデックスの列 (PK、パス、値) で Bツリー が作成されます。PK は基になるテーブルの主キーです。このインデックスは、XML インスタンス内でのプロパティ値の照合に役立ちます。
・ 最後の、VALUE インデックスにより、XML プライマリ インデックスの列 (値、パス) に Bツリー が作成されます。このインデックスは、ノード値が既知でも、クエリでパスが明確に指定されていない場合に役立ちます。これは、//author[last-name="Howard"] などの、descendant-or-self 軸の照合で一般的に行われます。ここで、<author> 要素は階層の任意のレベルで発生できます。また、/book [@* = "novel"] のような "ワイルドカード" クエリでも発生します。ここでは、クエリによって、"novel" という値を持ついくつかの属性により、<book> 要素が検索されます。さらに、型指定された XML 列の値ベースの範囲のスキャンで、VALUE インデックスが役立ちます。
128 レベルまでの XML 階層に適応できます。これよりも長いパスを含む XML インスタンスは、挿入および変更時に拒否されます。
同様に、ノードの値の最初の 128 バイトまでにインデックスが設定されます。これよりも長い値はシステム内に収容され、インデックスは設定されません。
例: パスベースの照合
次のクエリがワークロードで一般的に行われるとします。
SELECT xCol
FROM docs
WHERE xCol.exist ('/book[@genre = "novel"]') = 1
パス式 /book/@genre と値 "novel" が、PATH インデックスのキー フィールドに対応します。その結果、XML セカンダリ インデックスの種類 PATH が、このワークロードに役立ちます。
CREATE XML INDEX idx_xCol_Path on docs (xCol)
USING XML INDEX idx_xCol FOR PATH
例: オブジェクトのプロパティのフェッチ
テーブル T の各行から、プロパティ "genre"、"title"、および書籍の ISBN を取得する、以下のクエリについて考えてみます。
SELECT xCol.value ('(/book/@genre)[1]', 'varchar(50)'),
xCol.value ('(/book/title)[1]', 'varchar(50)'),
xCol.value ('(/book/@ISBN)[1]', 'varchar(50)')
FROM docs
この場合、PROPERTY インデックスが役立ちます。これは次のように作成されます。
CREATE XML INDEX idx_xCol_Property on docs (xCol)
USING XML INDEX idx_xCol FOR PROPERTY
例: 値ベースのクエリ
次のクエリでは、descendant-or-self 軸 (//) により、部分的なパスが指定されます。したがって、ISBN の値に基づく照合を行う場合に、VALUE インデックスが役立ちます。
SELECT xCol
FROM docs
WHERE xCol.exist ('//book[@ISBN = "1-8610-0157-6"]') = 1
VALUE インデックスは次のように作成されます。
CREATE XML INDEX idx_xCol_Value on docs (xCol)
USING XML INDEX idx_xCol FOR VALUE
・ コンテンツのインデックス設定
XML 列にはフルテキスト インデックスを作成できます。これにより、XML マークアップを無視して XML 値のコンテンツにインデックスを付けられます。属性値は、(マークアップの一部として考えられるので) フルテキスト インデックスが設定されません。また、トークンの境界として要素タグが使用されます。XML インデックスとフルテキスト インデックスの両方を XML 列に作成できます。また、フルテキスト検索と XML インデックスを組み合わせて使用できます。フルテキスト インデックスを最初のフィルタとして使用して選択を絞り込み、XQuery を次のフィルタに適用します。
CONTAINS() を使用したフルテキスト検索と、XQuery の contains() は、異なる意味合いを持っています。前者が語幹検索を使用したトークン検索であるのに対し、後者は部分文字列の検索です。
例: XML 列でのフルテキスト インデックスの作成
XML 列にフルテキスト インデックスを作成する手順は、他の SQL 型の列での手順とほぼ同じになります。基になるテーブルに一意キー列が必要です。DDL ステートメントは次のようになります。ここで、PK__docs__7F60ED59 はテーブルの単一列の主キー インデックスです。
CREATE FULLTEXT CATALOG ft AS DEFAULT
CREATE FULLTEXT INDEX ON dbo.docs (xCol) KEY INDEX PK__docs__7F60ED59
例: フルテキスト検索と XML クエリの組み合わせ
次のクエリでは、XML 値の書籍のタイトルに "Secure" という単語が含まれていることを確認します。
SELECT *
FROM docs
WHERE CONTAINS(xCol,'Secure')
AND xCol.exist('/book/title/text()[contains(.,"Secure")]') =1
CONTAINS() メソッドでは、フルテキスト インデックスを使用して、ドキュメントの任意の場所に "Secure" という単語を含む XML 値をサブセットとして取り出します。exist() 句により、書籍のタイトルに "Secure" という単語が出現していることが確認されます。
XMLインデックスを使用したクエリの実行
XML インデックスにより、クエリの実行速度が向上します。クエリは、常に、もしあれば、XML 列の XML プライマリ インデックスに対してコンパイルされます。クエリ全体 (リレーショナル データ部分と XML データ部分の両方) に対して、単一のクエリ プランが作成されます。これは、データベース エンジンのコストに基づくオプティマイザを使用して、最適化されます。クエリのオプティマイザのコストの推定に応じて、XML セカンダリ インデックスが選択されます。
XMLインデックスのカタログ ビュー
カタログ ビューでは、XML インデックスに関するメタデータ情報が提供されます。カタログ ビューの sys.indexes には、インデックスの "type" 3 を持つ XML インデックスのエントリが含まれます。"name" 列には、XML インデックスの名前が含まれます。
また、XML インデックスは、カタログ ビュー sys.xml_indexes にも記録されます。これには、sys.indexes のすべての列、および XML インデックスにとって意味を持ついくつかの特別な列が含まれます。列 "secondary_type" の値 NULL は、XML プライマリ インデックスを示します。値 'P'、'R' および 'V' は、PATH、PROPERTY および VALUE の XML セカンダリ インデックスをそれぞれ表します。
XML インデックスの領域の使用状況は、テーブル値関数 sys.fn_indexinfo() で求めることができます。たとえば、占有されたディスク ページの数、バイト単位の平均行サイズ、レコード数、および XML インデックスを含む、すべてのインデックスの種類のその他の情報などの情報が提供されます。この情報は、データベース パーティションごとに使用できます。つまり、XML インデックスでは、基になるテーブルと同じパーティション分割手法やパーティション分割関数が使用されます。
例: XML インデックスの領域の使用状況
SELECT sum(Pages)
FROM sys.fn_indexinfo ('docs', 'idx_xCol_Path' , DEFAULT, 'DETAILED')
これにより、すべてのパーティションに渡って、テーブル T の XML インデックス idx_xCol_Path によって占有されるディスク ページの数が算出されます。sum() 関数を使用しないと、パーティションごとのディスク ページの使用量が結果として返されます。
XMLスキーマ処理
XML スキーマは、システムではオプションです。前述のとおり、XML スキーマにバインドされていない XML データ型は、型指定されていないと見なされます。XML ノード値が Unicode 文字列として格納され、XML インスタンスが整形式であるかどうかが確認されます。型指定されていない XML 列には、インデックスを設定できます。
XML スキーマ コレクションと一緒に登録されたXML スキーマと、XML データ型とを関連付けることにより、XML 列の型指定が行われます。新しい DDL ステートメントを実行すると、1 つ以上の XML スキーマが登録されている XML スキーマ コレクションの作成が可能になります。XML スキーマ コレクションにバインドされた XML 列、パラメータまたは変数は、コレクションのすべての XML スキーマに応じて型が指定されます。XML スキーマ コレクションでは、対象となる名前空間を使用して、型システムによりそれぞれの XML スキーマが特定されます。
XML インスタンスの各最上位レベルの XML 要素では、要素が準拠する可能性のある空の対象名前空間を指定する必要があります。各最上位レベルの要素の対象名前空間に応じて、挿入時や変更時にデータが検証されます。バイナリ XML 表現は、関連付けられた XML スキーマ情報に基づいて型指定された値をエンコードし、十分に説明されています。したがって、型指定されていない XML データに比べ、再解析をより効率的に行えます。XML インデックスでも、値が適切に型指定されます (xs:decimal として XML スキーマで定義されている場合、/book/price は decimal として格納されます)。
クエリのコンパイル中に、型の確認のために XML スキーマが使用されます。また、型の不一致に対しては静的エラーが発行されます。また、クエリの最適化のために、クエリ コンパイラにより XML スキーマが使用されます。
データベース エンジンのメタデータ サブシステムには、XML の型情報が含まれています。たとえば、XML スキーマ コレクションおよびそれに含まれている XML スキーマ、およびプリミティブ XSD とリレーショナル型システムとの間のマッピングなどです。ほとんどすべての W3C XML Schema 1.0 仕様 (http://www.w3.org/TR/2001/REC-XMLSCHEMA-1-20010502/ および http://www.w3.org/TR/2001/REC-XMLSCHEMA-2-20010502/ を参照してください) がサポートされています。XML スキーマ ドキュメント内のコメントや注釈は保持されません。また、key/keyref はサポートされません。
XMLスキーマ コレクション
XML スキーマ コレクションはメタデータ エンティティであり、リレーショナル スキーマによってスコープが設定され、(たとえば、<xs:import> を使用して) 関連する、または関連しない 1 つ以上の XML スキーマが含まれます。XML スキーマ コレクション内の個別の XML スキーマは、対象名前空間を使用して特定されます。XML スキーマ コレクションは、ほぼテーブルと同様に利用できるエンティティです。
XML スキーマ コレクションは、CREATE XML SCHEMA COLLECTION 構文を使用して作成されます。また、1 つ以上の XML スキーマを提供します。その後、XML スキーマ コレクションを使用して XML 列を型指定できます。このデザインにより、柔軟なデータ モデルが実現されます。このデータ モデルでは、異なる XML スキーマに応じて型指定された XML データを同じ列に格納できます。このデザインは、XML スキーマの数が多くなると、特に便利です。さらに、このデザインでは、XML スキーマの展開がある程度サポートされます。
また、型指定されている XML 列での、オプションの DOCUMENT または CONTENT により、XML ツリーまたはフラグメントのそれぞれを XML 列に格納可能かどうかが指定されます。既定では CONTENT が指定されています。DOCUMENT では、それぞれの XML インスタンスが検証され、型指定された XML に応じて、最上位レベル要素の対象名前空間を指定する必要があります。それに対して CONTENT では、それぞれの最上位要素は、XML スキーマ コレクション内の任意の対象名前空間を指定できます。XML インスタンスは、インスタンスで発生しているすべての対象名前空間に応じて、検証され、型指定されます。
例: XML スキーマ コレクションの作成
XML スキーマを対象名前空間 http://myBooks と使用して、XML インスタンスの型指定を行うとします。以下に示すように、XML スキーマ コレクション myCollection を作成し、myCollection のコンテンツとして XML スキーマを指定します。
CREATE XML SCHEMA COLLECTION myCollection AS
'<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://myBooks"
elementFormDefault="qualified"
targetNamespace="http://myBooks">
<xsd:element name="bookstore" type="bookstoreType" />
<xsd:complexType name="bookstoreType">
<xsd:sequence maxOccurs="unbounded">
<xsd:element name="book" type="bookType" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="bookType">
<xsd:sequence>
<xsd:element name="title" type="xsd:string" />
<xsd:element name="author" type="authorName" />
<xsd:element name="price" type="xsd:decimal" />
</xsd:sequence>
<xsd:attribute name="genre" type="xsd:string" />
<xsd:attribute name="publicationdate" type="xsd:string" />
<xsd:attribute name="ISBN" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="authorName">
<xsd:sequence>
<xsd:element name="first-name" type="xsd:string" />
<xsd:element name="last-name" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>'
XML スキーマが登録されている myCollection に対して、新しいメタデータ エンティティが作成されます。
XMLスキーマ コレクションの変更
ALTER XML SCHEMA COLLECTION ステートメントを実行すると、新しい最上位レベルのスキーマ コンポーネントを持つ XML スキーマ コレクション内の XML スキーマ拡張がサポートされます。また、XML スキーマ コレクションへの新しい XML スキーマの登録もサポートされます。このことを、次の例で示します。
例: XML スキーマ コレクションの変更
次のステートメントは、対象名前空間 http://myDVD を持つ新しい XML スキーマを、XML スキーマ コレクション myCollection に追加する方法を示しています。
ALTER XML SCHEMA COLLECTION myCollection ADD
'<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://myDVD"
elementFormDefault="qualified"
targetNamespace="http://myDVD">
<xsd:element name="dvdstore" type="dvdstoreType" />
<xsd:complexType name="dvdstoreType">
<xsd:sequence maxOccurs="unbounded">
<xsd:element name="dvd" type="dvdType" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="dvdType">
<xsd:sequence>
<xsd:element name="title" type="xsd:string" />
<xsd:element name="price" type="xsd:decimal" />
</xsd:sequence>
<xsd:attribute name="genre" type="xsd:string" />
<xsd:attribute name="releasedate" type="xsd:string" />
</xsd:complexType>
</xsd:schema>'
XMLスキーマ コレクションのカタログ ビュー
XML スキーマ コレクションの SQL カタログ ビューにより、ユーザーは個別の XML スキーマ名前空間のコンテンツを再構成できます。XML スキーマ コレクションが、カタログ ビュー sys.xml_schema_collections に列挙されます。XML スキーマ コレクション "sys" がシステムにより定義されます。これには事前定義された名前空間が含まれており、明示的に読み込まなくても、すべてのユーザー定義の XML スキーマ コレクションで使用できます。このリストには、xml、xs、xsi、fn、および xdt の名前空間が含まれています。
言及しておくべき 2 つのカタログ ビューもあります。各 XML スキーマ コレクション内のすべての名前空間を列挙する sys.xml_schema_namespaces と、各 XML スキーマ内のすべての XML スキーマ コンポーネントを列挙する sys.xml_components です。
組み込み関数 XML_SCHEMA_NAMESPACE() では、リレーショナル スキーマの名前、XML スキーマ コレクション、およびオプションで XML スキーマの対象名前空間を受け取ります。この関数からは XML スキーマを含む XML データ型インスタンスが返されます。対象名前空間引数が省略された場合、組み込み関数により、事前定義された XML スキーマを除く、XML スキーマ コレクションのすべての XML スキーマを含む XML インスタンスが返されます。
例: XML スキーマ コレクションの XML 名前空間の列挙
XML スキーマ コレクション "myCollection" に次のクエリを使用します。
SELECT XSN.name
FROM sys.xml_schema_collections XSC
JOIN sys.xml_schema_namespaces XSN ON
(XSC.xml_collection_id = XSN.xml_collection_id)
WHERE XSC.name = 'myCollection'
例: XML スキーマ コレクションから指定した XML スキーマを出力
次のステートメントを実行すると、(リレーショナル) スキーマ dbo 内の XML スキーマ コレクション "myCollection" から、対象名前空間 http://myBooks を持つ XML スキーマが出力されます。
SELECT XML_SCHEMA_NAMESPACE (N'dbo', N'myCollection',
N'http://myBooks')
XMLスキーマ コレクションでのアクセス制御
XML スキーマ コレクションは、SQL Server 2005 のセキュリティ モデルを使用して、SQL オブジェクトのようにセキュリティで保護できます。プリンシパルに特権を許可して、データベース内に XML スキーマ コレクションを作成できます。各 XML スキーマ コレクションにより、ALTER、CONTROL、TAKE OWNERSHIP、REFERENCES、EXECUTE、および VIEW DEFINITION がサポートされます。
ALTER XML SCHEMA COLLECTION ステートメントを実行するには、ALTER 権限が必要になります。
ALTER AUTHORIZATION ステートメントの実行によって、あるプリンシパルから他のプリンシパルに XML スキーマ コレクションの所有権を転送するには、TAKE OWNERSHIP 権限が必要になります。
たとえば、XML 列やパラメータの型指定や制約を行うためにスキーマのバインドが必要な場合は、状況にかかわらず、REFERENCES 権限により、XML スキーマ コレクションを使用する権限がプリンシパルに与えられます。
XML スキーマ コレクションに対して、プリンシパルによって挿入または更新された値を検証するには、EXECUTE 権限が必要になります。また、XML データ型を使用して、型指定された XML 列、変数、およびパラメータの値に対してクエリを行う際にも、EXECUTE 権限が必要になります。
VIEW DEFINITION 権限により、XML スキーマ コレクションと、それに含まれるすべての XML スキーマ、およびそれらの XML スキーマに含まれるすべてのスキーマ コンポーネントに対応するカタログ ビューの行に、プリンシパルからアクセスできます。
CONTROL 権限により、DROP XML SCHEMA COLLECTION ステートメントを使用した XML スキーマ コレクションの削除を含むあらゆる操作を、XML スキーマ コレクション上で実行する権限がプリンシパルに与えられます。これには、XML スキーマ コレクションに対する他の権限が含まれています。
テーブルまたは XML 列上での他の権限以外に、XML スキーマ コレクションでの権限が必要になります。プリンシパルでは、テーブルを作成するための権限が必要ですが、XML スキーマ コレクション C に応じて型指定された XML 列 X を持つテーブル T を作成するためには、C に REFERENCES 権限が必要になります。プリンシパルが XML スキーマ コレクション C で EXECUTE 権限を持っている場合、列 X にデータを挿入する権限を持っているプリンシパルは、データを挿入できます。同様に、XML データ型メソッドを使用して列 X でデータのクエリを行うには、プリンシパルでは、列 X に SELECT 権限、C に EXECUTE 権限が必要になります。ただし、SELECT X FROM T や SELECT * FROM T などのように、列 X から XML 値全体を取得するためには、X に SELECT 権限があれば十分です。
プリンシパルの権限を無効にすることができます。また、SQL Server 2005 のセキュリティ モデル設定に応じて、プリンシパルの権限を拒否できます。
カタログ ビューの表示
XML スキーマ コレクションに ALTER、TAKE OWNERSHIP、REFERENCES、VIEW DEFINITION、または CONTROL 権限を持つプリンシパルは、XML スキーマ コレクション、それに含まれている XML スキーマ、およびそれらの XML スキーマ コンポーネントのカタログ ビューの行にアクセスできます。また、組み込み関数 XML_SCHEMA_NAMESPACE() を使用して、プリンシパルも XML スキーマ コレクションのコンテンツにアクセスできます。
プリンシパルの VIEW DEFINITION 権限が拒否された場合、プリンシパルは、カタログ ビューの XML スキーマ コレクションにアクセスしたり、または XML_SCHEMA_NAMESPACE() を使用できません。
FOR XMLの機能強化
TYPE ディレクティブにより、XML 列、変数、またはパラメータに割り当て可能な XML データ型インスタンスが生成されます。または XML データ型メソッドを使用してクエリが行われます。これにより、SELECT ... FOR XML TYPE ステートメントを入れ子にできます。
PATH モードにより、ユーザーは列の値を表示する XML ツリー内のパスを指定できます。前述の入れ子と組み合わせると、FOR XML EXPLICIT よりも記述が簡単ですが、階層が深い場合は FOR XML EXPLICIT ほどのパフォーマンスが得られない場合があります。
ELEMENTS と共に使用されているディレクティブ XSINIL により、属性 xsi:nil="true" を持つ要素に NULL がマップされます。新しい ROOT ディレクティブにより、ルート ノードを FOR XML のすべてのモードで指定できます。新しい XMLSCHEMA ディレクティブにより、XSD インライン スキーマが生成されます。
強化点および例の詳細については、2004 年 6 月に MSDN によって公開される予定の「What's New in FOR XML in Microsoft SQL Server (英語)」(Michael Rys 著) を参照してください。
パフォーマンスのガイドライン
XML データ モデルは、リレーショナル データ モデルよりも機能が豊富で複雑になります。XML データ モデルによって複雑なデータを作成できますが、階層関係やデータ内でのドキュメントの順序を維持する必要もあります。XML ノード識別子に基づいた並べ替えによって、ドキュメントの順序が保持されます。これにより、同時に階層関係も保持されます。これらは、より複雑なクエリ プランに役立ちます。
より適切なパフォーマンスを維持するためには、構造化されたデータをテーブルのリレーショナル列に格納する必要があります。データが半構造化されているか、または構造化されておらず、かつ XML マークアップが含まれている場合、モデリングを行えるようにするために XML データ モデルを選択します。ただし、パフォーマンスの向上は期待できません。XML スキーマは、クエリの最適化を支援します。
SQL Server CLRでの XML サポート
SQL Server CLR サポートを使用すると、マネージ コードでサーバー側のロジックを記述して、ビジネス ルールを設定できます。このビジネス ロジックは、いくつかの方法で XML データに追加できます。
・ マネージ コードで SQLCLR 関数を記述して XML 値を渡したり、System.Xml 名前空間によって提供された XML 処理機能を使用できます。XSL 変換を XML データに適用する例を以下に示します。または、XML 列 を 1 つ以上のマネージ クラスにシリアル化解除し、マネージ コードを使用して操作を行うことができます。
・ ビジネス ニーズに合わせて、XML 列で処理を呼び出す T-SQL ストアド プロシージャや関数を記述できます。
例: XSL 変換の適用
XML データ型インスタンスやファイルに格納された XSL 変換を受け取る CLR 関数 TransformXml() を考えてみます。この関数は、変換を XML データに適用し、変換された XML データを結果として返します。C# で記述されたスケルトン関数は、次のようになります。
public static SqlXml TransformXml (SqlXml XmlData, string xslPath) {
// XSL 変換を読み込みます
XslTransform xform = new XslTransform();
XPathDocument xslDoc = new XPathDocument (xslPath);
xform.Load (xslDoc.CreateNavigator(),null);
// XML データを読み込みます
XPathDocument xDoc = new XPathDocument (XmlData.CreateReader());
XPathNavigator nav = xDoc.CreateNavigator ();
// 変換した値を返します
SqlXml retSqlXml = new SqlXml (xform.Transform(nav, null));
return (retSqlXml);
}
アセンブリが登録され、TransformXml() に対応するユーザー定義 T-SQL 関数 SqlXslTransform() が作成されると、次のクエリのように、T-SQL から関数を呼び出せます。
SELECT SqlXslTransform (xCol, 'C:\yukon\xsltransform.xsl')
FROM T
WHERE xCol.exist('/book/title/text()[contains(.,"custom")]') =1
クエリ結果には、変換された XML データの行セットが含まれています。
SQLCLR により、まったく新しい世界が開けます。SQLCLR は、テーブルへの XML データの分解やプロパティの昇格、System.Xml 名前空間内のマネージ クラスを使用した XML データのクエリに使用できます。詳細については、SQL Server 2005 および Visual Studio 2005 の Books Online を参照してください。
SQL Server 2005でのクライアント側の XML 処理
XMLデータ型のクライアント側サポート
.NET Framework V2.0での ADO.NET XML サポート
SqlDataReader.GetSqlXml() メソッドの System.Data.SqlTypes 名前空間のクラス SqlXml として、XML データ型が公開されます。SqlXml.CreateReader() 関数を使用すると、SqlXml オブジェクトから XmlReader を取得できます。
XML 列を型指定する、XML スキーマ コレクションの 3 部構成の名前を、データベースの名前 (XmlSchemaCollectionDatabase)、リレーショナル スキーマ (XmlSchemaCollectionOwingSchema) および XML スキーマ コレクション (XmlSchemaCollectionName) を示す 3 つのプロパティとして、(SqlDataReader オブジェクトの GetSchemaTable() または GetSqlMetaData (int) を使用して) XML 列メタデータから取得できます。
新しいスキーマの行セット XMLSCHEMA は、サーバーから XML スキーマを取得するためにクライアントで使用できます。XMLSCHEMA 行セットには、XML スキーマ コレクション、対象名前空間、および XML スキーマ コンテンツ自体の 3 つの列が含まれています。
次の例では、XML データ型へのマネージ アクセスのためのスケルトン コードを示しています。
例: XML データ型へのインプロセス アクセス
以下の C# コードでは、XML データ型がどのようにしてインプロセス プロバイダからアクセスできるかを例示しています。SQL クライアント アクセスのコードを適切に変更するには、インプロセス アクセスが必要になります。
using System;
using System.Xml;
using System.Data;
using System.Data.SqlTypes;
using System.Data.SqlServer;
class xmldtADONETReadAccessInProc
{
static void ReadXmlDataType () {
// サーバーへのインプロセス接続
SqlConnection conn = SqlContext.GetConnection();
// XML データを選択するためにクエリを準備します
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT xCol FROM docs";
// クエリを実行し、結果データを取得します
SqlDataReader r = cmd.ExecuteReader();
r.Read();
// 行セット内の XML データ型フィールドにアクセスします
SqlXml xml = r.GetSqlXml(0);
new XmlTextWriter(Console.Out).WriteNode(
xml.CreateReader(), true);
}
}
例: SQL クライアント プロバイダを使用した XML データ型列の更新
以下のコードでは、SQL クライアント プロバイダを使用して XML 列の値を置き換えるメソッド WriteXmlDataType() を示しています。インプロセス プロバイダのコードは、このコードと類似しています。
using System;
using System.Xml;
using System.Data;
using System.Data.SqlTypes;
using System.Data.SqlClient;
class xmldtADONETUpdateAccess
{
static void WriteXmlDataType () {
// サーバーへの接続
SqlConnection conn = new SqlConnection("server=server1;" +
" database=XMLtest; Integrated Security=SSPI");
conn.Open();
// サーバーで XML 列を更新します
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "UPDATE docs SET xCol=@x WHERE id=1";
// XML パラメータの値を設定します
SqlParameter p = cmd.Parameters.Add("@x", SqlDbType.Xml);
p.Value = new SqlXml(new XmlTextReader("<hello/>",
XmlNodeType.Document, null));
// 更新を実行し、接続を閉じます
cmd.ExecuteNonQuery();
conn.Close();
}
}
SQLネイティブ クライアント アクセス
新しい SQL ネイティブ アクセス (SQLNCLI) の OLE DB プロバイダでは、Unicode 文字列 (DBTYPE_XML、DBTYPE_BSTR、DBTYPE_WSTR、および DBTYPE_VARIANT) または ISequentialStream を使用した Unicode 文字ストリームとして、XML データ型の列を取得できます。既定は DBTYPE_XML です。
3 部構成の XML スキーマ コレクションの名前は、IDBSchemaRowset::GetRowset() によって返される COLUMNS スキーマ行セットの3 つの新しい列にあります。SS_XML_CATALOGNAME により、カタログの名前が与えられます。また、SS_XML_SCHEMANAME により、XML スキーマ コレクションがあるリレーショナル スキーマの名前が、SS_XML_SCHEMACOLLECTIONNAME により、XML スキーマ コレクションの名前が与えられます。これらの名前は DBTYPE_WSTR 型です。これらの列が型指定されていない XML 列である場合は NULL 値が設定されます。
同様の変更が、PROCEDURE_PARAMETERS スキーマの行セットと IColumnRowset:GetColumnRowset() に対して行われました。
XML スキーマ コレクションのコンテンツを取得するために、XML_SCHEMA_NAMESPACE() への呼び出しでこれらの名前を使用して、クライアントはサーバーに独立したアクセスを行い、XML データ型として XML スキーマを返すことができます。または、新しい SS_XMLSCHEMA スキーマの行セットを持つ IDBSchemaRowset により、カタログ名、リレーショナル スキーマ名、XML スキーマ コレクション名、対象名前空間、および XML スキーマが返されます。
SQLNCLI を使用した ODBC アクセスでは、SQL_SS_XML という、可変長の Unicode 文字データにXML データ型がマップされます。3 部構成の XML スキーマ コレクションの名前は、XML 列の SqlColAttribute により、CharacterAttributePtr として表されます。これらのフィールド識別子は、データベース、リレーショナル スキーマ、および XML スキーマ コレクションのそれぞれの名前に対して、SQL_DESC_SS_XML_SCHEMA_CATALOG_NAME、SQL_DESC_SS_XML_SCHEMA_SCHEMA_NAME、および SQL_DESC_SS_XML_SCHEMA_COLLECTION_NAME になります。
SQL ネイティブ クライアントを取得するためには、ユーザーは、SQL Server 2005 リリースのデータベース サーバーまたはクライアント ツールをインストールする必要があります。MDAC 2.8 ADO を使用した、XML データ型への OLE DB アクセスは、この資料の執筆時点では使用できません。
XMLとリレーショナル スキーマとの間での SQLXML マッピング
SQLXML マッピング テクノロジを使用して、リレーショナル データの論理的な XML ビューを作成できます。特別な注釈を任意の XSD スキーマに追加することにより、"マッピング" または "注釈付きスキーマ" とも呼ばれる XML ビューが作成されます。その後、他の SQLXML テクノロジによりこの注釈付きのスキーマが使用され、論理的な XML ビューに対するクエリや更新を変換して、リレーショナル テーブルに対してクエリや更新を行うことができます
・ XML ビューが XPath クエリと組み合わされると、SQLXML によって、FOR XML クエリが生成され、要求されたデータを検索して、スキーマで指定されたとおりに形成します。
・ 注釈付きスキーマと組み合わせると、SQLXML アップデートグラムは、XML インスタンスへの変更を表します。SQLXML アップデートグラムは、オプティミスティック同時実行を使用して、これらの変更をリレーショナルでの変更に戻して確定し、適切なデータが更新されるようにします。
・ SQLXML 一括読み込みでは、XML ビューを使用し、XML データがリレーショナル テーブルに "細分化" されます。
これらのトピックの詳細については、「SQLXML documentation」(英語) を参照してください。
リレーショナル テーブルの XML ビューの作成
データベースの XML ビューを作成するには、XML データの XSD スキーマから開始します。データベース テーブルまたはビューの行は、スキーマで複雑な型の要素にマップされます。データベースの列値は、属性または単純型の要素にマップされます。
既定では、明示的な注釈が提供されない場合、SQLXML によって、複雑な型の要素がテーブルにマップされ、単純型の要素や属性が列にマップされると推測されます。これは、要素や属性の名前が、データベースのテーブルや列の名前とまったく同じである場合のみ機能します。
要素または属性の名前が、テーブルまたはビューあるいはマップされる列名と同じ名前でない場合、明示的なマッピングを行う必要があります。XML ドキュメント内の要素や属性と、データベースのテーブル (ビュー) または列との間のマッピングを指定するために、次の注釈が使用されます。
・ **sql:relation:**XML 要素をデータベース テーブルにマップします。
・ sql:field **:**要素または属性をデータベースの列にマップします。
XMLビューで階層を作成するための、リレーションシップのマッピング
データベースでは、外部キー リレーションシップによってテーブルを関連付けることができます。XML では、入れ子になった要素の階層によって、これらと同じリレーションシップが表されます。マッピングで適切な入れ子を構成するために、要素がどのように関連するかを指定する必要があります。sql:relationship 注釈を使用して、マッピング スキーマ要素間でこれらのリレーションシップを確立できます。この注釈では、親テーブルと子テーブルを指定できます。また、結合を行うために、それぞれのどの列を使用するかも指定できます。その後、SQLXML によってこの情報が使用され、マッピングのための適切な入れ子の階層が構成されます。
使用していないデータを格納するための、オーバーフローの使用
XML データが正規構造を持っているときに、マッピングが機能します。しかし、XML データには、構造化されていないデータや、特定の列にマップされていないデータがいくつか存在する場合があります。このデータを格納し、後で取得するために、sql:overflow 注釈を使用できます。sql:overflow 注釈により、すべての使用されないデータが格納され、またクエリを行うときにデータの取得元の列が指定されます。
また、オーバーフロー列により、データベースに追加することなく XML 構造を拡張できます。データベースに格納用の列を追加することなく、XML 構造にいつでも要素や属性を追加できます。これらは単に、オーバーフロー フィールドに格納され、適切な時点に取得されます。
関連情報
XML ビューの作成とマッピングの例の詳細については、「Creating XML Views by Using Annotated XSD Schemas」(英語) を参照してください。
XPathを使用した XML ビューのクエリ
データベースの XML ビューを作成すると、XPath クエリ言語を使用して、まるで実際の XML ドキュメントのようにビューに対してクエリを行えます。SQLXML によって、XPath 1.0 クエリ言語のサブセットがサポートされます。マッピングに対して XPath が発行されると、SQLXML によりそれらが 1つに構成され、SQL Server に送信される FOR XML EXPLICIT ステートメントが作成されます。適切なデータが取得され、マッピングに応じて形成されます。
XML ビューでサポートされる XPath のサブセットの詳細については、SQLXML ドキュメントを参照してください。
アップデートグラムを使用した XML ビューによる更新
SQL Server では、データベースの XML ビューに対してアップデートグラムを使用し、XML ビュー経由でデータベースを変更 (挿入、更新、または削除) できます。
アップデートグラムの構造
アップデートグラムは、アップデートグラムの構文を形成する <sync> 要素、<before> 要素、および <after> 要素を持つ XML ドキュメントです。各 <sync> ブロックには、1 つ以上の <before> ブロックと <after> ブロックが含まれています。<before> により、レコード インスタンスの既存の状態 ("前の状態" とも呼ばれます) が識別されます。<after> により、データが変更された後の新しい状態が識別されます。アップデートグラムにより、レコード インスタンスが削除、挿入、または更新されるかは、<before> ブロックと <after> ブロックのコンテンツに依存します。
挿入操作
レコード インスタンスが <after> ブロックに表示されているのに、対応する <before> ブロックには表示されない場合、アップデートグラムによって挿入操作が指示されます。この場合、アップデートグラムによって、<after> ブロックのレコードがデータベースに挿入されます。
削除操作
レコード インスタンスが <before> ブロックに表示されているのに、対応するレコードが <after> ブロックには表示されない場合、アップデートグラムにより削除操作が指示されます。この場合、アップデートグラムによって、<before> ブロックのレコードがデータベースから削除されます。
アップデートグラムで指定された要素がテーブルの複数の行と一致するか、またはどのテーブルの行にも一致しない場合、アップデートグラムによりエラーが返され、<sync> ブロック全体がキャンセルされます。アップデートグラムの要素で一度に削除できるレコードは 1 つだけです。
更新操作
既存のデータを更新するときは、<before> ブロックと <after> ブロックの両方を指定する必要があります。データベースの既存のレコードを識別するために、アップデートグラムにより <before> ブロックで指定された要素が使用されます。<after> ブロックの対応する要素により、更新操作を実行した後、レコードがどのように見える必要があるのかが示されます。
<before> ブロックの要素は、データベースの 1 つのテーブルの行のみと一致する必要があります。要素が複数のテーブルの行と一致するか、またはどのテーブルの行にも一致しない場合、アップデートグラムによりエラーが返され、<sync> ブロック全体がキャンセルされます。
関連情報
XML ビュー経由でデータを変更するためのアップデートグラムの作成および使用の詳細については、「Using Updategrams to Modify Data」(英語) を参照してください。
XMLビューによる XML データの一括読み込み
XML 一括読み込みは、XML データの SQL Server テーブルへの読み込みを可能にする COM オブジェクトです。INSERT ステートメントおよび OpenXML 関数を使用して、XML データを SQL Server データベースに挿入できますが、大量の XML データを挿入する必要がある場合、一括読み込みユーティリティにより、より優れたパフォーマンスが提供されます。XML 一括読み込みによりマッピング スキーマが解釈され、XML データが挿入されるテーブルが特定されます。その後、XML データがリレーショナル テーブルに細分化されます。
ソースの XML ドキュメントは大きくなる可能性があるので、一括読み込み処理では、メモリにドキュメント全体が読み込まれません。代わりに、XML 一括読み込みにより XML データがストリームとして解釈され、ストリームとして読み取るように解釈されます。ユーティリティによってデータが読み取られるとき、データベース テーブルが特定され、XML データ ソースから適切なレコードが生成されます。その後、レコードが SQL Server に送信されて挿入されます。
一括読み込みが機能する方法および使用方法の詳細については、「Performing Bulk Load of XML Data」(英語) を参照してください。
SQLXMLデータ アクセス メソッド
SQL Server 2000 以後、SQLXML 機能にアクセスするための 2 つの新しい方法が追加されました。
・ SQLXML マネージ クラス
・ SQLXML Web サービス
また、テンプレート内でアップデートグラムをサポートするように、SQL Server への HTTP アクセスが機能拡張されました。
SQLXMLマネージ クラス
SQLXML マネージ クラスにより、Microsoft .NET Framework 内の SQLXML 3.0 機能が公開されます。SQLXML マネージ クラスにより、SQL Server のインスタンスから XML データにアクセスし、.NET Framework 環境にデータを移動し、データを処理し、更新を SQL Server に送り返して適用する C# アプリケーションを記述できます。
SQLXML マネージ クラスの使用方法の詳細については、「SQLXML .NET Support」(英語) を参照してください。
SQLXML Webサービス
SQLXML での Web サービスのサポートにより、SQL Server の機能をクライアントに提供する Web サービスとして、SQL Server が公開されます。SQLXML が実行されているサーバーに SOAP HTTP 要求を送信して、ストアド プロシージャ、ユーザー定義関数 (UDF)、およびテンプレートを実行できます。
また、SQL Server ユーティリティのために含まれている IIS 仮想ディレクトリ管理を使用して、Web サービスもセットアップされます。Web サービス仮想ディレクトリがセットアップされたら、ストアド プロシージャやテンプレートをサイトに追加できます。クライアントは、SOAP プロトコルにより、HTTP 経由でこれらのサービスにアクセスできます。
SQL Server 2005 では、サーバー内に Web サービスのネイティブ サポートが含まれています。ただし、SQLXML のみが、Web サービス経由の XML テンプレートへのアクセスをサポートします。また、データベース サーバー以外のサーバーに SQLXML がセットアップされ、データベースから離れた独立した中間層コンピュータをセットアップできます。
SQLXML Web サービスの詳細については、「Web Services (SOAP) Support in SQLXML」(英語) を参照してください。
まとめ
この資料では、SQL Server 2005 での XML サポートの補完テクノロジについて説明しました。サーバー側の機能には、XML ストレージ、インデックス設定、およびクエリ処理のネイティブ実装があります。FOR XML や OpenXML などの、既存の機能も強化されています。クライアント側のサポートには、XML データ型をサポートしたり、System.Xml で、異なるソースの XML データに対してクエリを行うための XQuery をサポートする ADO.NET への機能拡張があります。また、SQLXML マッピング テクノロジの Web リリース機能拡張が、SQL Server 2005 に組み込まれています。
サーバー側とクライアント側のサポートは、さまざまなシナリオで役立ちます。XML データ型では、XML データを型指定されていない XML 列に挿入することにより、XML データの格納の単純なメカニズムが提供されます。型指定された XML 列を定義するために XML スキーマを使用することにより、データの検証に加え、データベース エンジンによるストレージやクエリ処理の最適化に役立ちます。
XML データ型により、ドキュメントの順序が保持されます。これは、たとえばドキュメント管理のようなアプリケーションに役立ちます。また、再帰 XML スキーマも処理できます。クエリや更新が重要でないシナリオにとっては [n]varchar(max) が最適な選択肢ですが、既知のスキーマを持つ構造化されたデータにとっては、リレーショナル データ モデルが今もなお最善の選択肢です。
サーバーのテーブルに格納されたリレーショナル データで、XML 中心のプログラミング モデルを使用するときは、いつでも、SQLXML マッピング テクノロジが役立ちます。マッピングは、XML ビューとしての XML スキーマの定義に基づいています。マッピングは、テーブルへの XML データの一括読み込み、および XPath 1.0 を使用したテーブルのクエリに使用できます。ドキュメントの順序が保持されないため、ドキュメント処理とは対照的に、XML データ処理にはマッピング テクノロジが役立ちます。
今後の .NET Framework V2.0 ベータ 1 リリースでは、System.Xml の中核的な XML クラスにより、XML データの読み取り、書き込み、操作、および変換が可能になります。パフォーマンス、使いやすさ、型指定、およびクエリの強化により、V2.0 リリースでの XML サポートは、革新、標準サポート、および使いやすさにおいて業界をリードし続けます。これには、SQL Server 外部の XML のソースを操作するための、XQuery プロセッサが含まれます。
サーバー側とクライアント側のテクノロジは、相互補完します。マッピング テクノロジは、サーバー側の機能を活用して、その機能を補強できます。たとえば、ドキュメントの順序や再帰スキーマの管理など、アプリケーションのより多くの分野で活用できます。一方、CLR により拡張性がもたらされ、XSLT 変換などの既存の XML ツールの機能を XML データ型に移行できます。サーバーとクライアントでの XQuery の実装は、相互に調整され、2003 年 11 月の XQuery の仕様のドラフトに合わせられています。XML スキーマの実装は、サーバー側と中間層の実装との間で調整されます。