Transact-SQL キーワードである OPENXML は、テーブルやビューに似たメモリ内 XML ドキュメントに対して行セットを提供します。 OPENXML では、リレーショナル行セットであるかのように XML データにアクセスできます。 これを行うには、XML ドキュメントの内部表現の行セット ビューを提供します。 行セット内のレコードは、データベース テーブルに格納できます。
OPENXML は、行セット プロバイダー、ビュー、または OPENROWSET をソースとして表示できる場所であれば、SELECT および SELECT INTO ステートメントで使用できます。 OPENXML の構文については、 OPENXML (Transact-SQL) を参照してください。
OPENXML を使用して XML ドキュメントに対するクエリを記述するには、最初に sp_xml_preparedocument
を呼び出す必要があります。 これにより、XML ドキュメントが解析され、使用する準備ができている解析済みドキュメントへのハンドルが返されます。 解析されたドキュメントは、XML ドキュメント内のさまざまなノードのドキュメント オブジェクト モデル (DOM) ツリー表現です。 ドキュメント ハンドルは OPENXML に渡されます。 OPENXML は、渡されたパラメーターに基づいて、ドキュメントの行セット ビューを提供します。
注
sp_xml_preparedocument
は、SQL で更新されたバージョンの MSXML パーサーを使用しています Msxmlsql.dll。 このバージョンの MSXML パーサーは、SQL Server をサポートするように設計されており、MSXML バージョン 2.6 との下位互換性を維持します。
メモリを解放するには、 sp_xml_removedocument システム ストアド プロシージャを呼び出して、XML ドキュメントの内部表現をメモリから削除する必要があります。
次の図がプロセスを示します。
OPENXML を理解するには、XPath クエリに関する知識と XML の理解が必要であることに注意してください。 SQL Server での XPath サポートの詳細については、「 SQLXML 4.0 での XPath クエリの使用」を参照してください。
注
OpenXML を使用すると、行と列の XPath パターンを変数としてパラメーター化できます。 このようなパラメーター化により、プログラマが外部ユーザーにパラメーター化を公開した場合 (たとえば、外部から呼び出されたストアド プロシージャを介してパラメーターが提供されている場合) は、XPath 式の挿入につながる可能性があります。 このような潜在的なセキュリティの問題を回避するために、XPath パラメーターを外部の呼び出し元に公開しないことをお勧めします。
例
次の例は、INSERT
ステートメントと SELECT
ステートメントでのOPENXML
の使用を示しています。 サンプル XML ドキュメントには、 <Customers>
要素と <Orders>
要素が含まれています。
最初に、 sp_xml_preparedocument
ストアド プロシージャは XML ドキュメントを解析します。 解析されたドキュメントは、XML ドキュメント内のノード (要素、属性、テキスト、およびコメント) のツリー表現です。
OPENXML
次に、この解析された XML ドキュメントを参照し、この XML ドキュメントのすべてまたは一部の行セット ビューを提供します。
OPENXML
を使用するINSERT
ステートメントは、このような行セットからデータベース テーブルにデータを挿入できます。 複数の OPENXML
呼び出しを使用して、XML ドキュメントのさまざまな部分の行セット ビューを提供し、たとえば、それらを異なるテーブルに挿入することによって処理できます。 このプロセスは、XML をテーブルに細分化とも呼ばれます。
次の例では、<Customers>
要素がCustomers
テーブルに格納され、<Orders>
要素が 2 つのINSERT
ステートメントを使用してOrders
テーブルに格納されるように XML ドキュメントが細断されます。 この例では、XML ドキュメントからCustomerID
とOrderDate
を取得するOPENXML
を含むSELECT
ステートメントも示しています。 プロセスの最後の手順では、 sp_xml_removedocument
を呼び出します。 これは、解析フェーズ中に作成された内部 XML ツリー表現を格納するために割り当てられたメモリを解放するために行われます。
-- Create tables for later population using OPENXML.
CREATE TABLE Customers (CustomerID varchar(20) primary key,
ContactName varchar(20),
CompanyName varchar(20));
GO
CREATE TABLE Orders( CustomerID varchar(20), OrderDate datetime);
GO
DECLARE @docHandle int;
DECLARE @xmlDocument nvarchar(max); -- or xml type
SET @xmlDocument = N'<ROOT>
<Customers CustomerID="XYZAA" ContactName="Joe" CompanyName="Company1">
<Orders CustomerID="XYZAA" OrderDate="2000-08-25T00:00:00"/>
<Orders CustomerID="XYZAA" OrderDate="2000-10-03T00:00:00"/>
</Customers>
<Customers CustomerID="XYZBB" ContactName="Steve"
CompanyName="Company2">No Orders yet!
</Customers>
</ROOT>';
EXEC sp_xml_preparedocument @docHandle OUTPUT, @xmlDocument;
-- Use OPENXML to provide rowset consisting of customer data.
INSERT Customers
SELECT *
FROM OPENXML(@docHandle, N'/ROOT/Customers')
WITH Customers;
-- Use OPENXML to provide rowset consisting of order data.
INSERT Orders
SELECT *
FROM OPENXML(@docHandle, N'//Orders')
WITH Orders;
-- Using OPENXML in a SELECT statement.
SELECT * FROM OPENXML(@docHandle, N'/ROOT/Customers/Orders') WITH (CustomerID nchar(5) '../@CustomerID', OrderDate datetime);
-- Remove the internal representation of the XML document.
EXEC sp_xml_removedocument @docHandle;
次の図は、sp_xml_preparedocumentを使用して作成された前の XML ドキュメントの解析済み XML ツリーを示しています。
OPENXML パラメーター
OPENXML のパラメーターは次のとおりです。
XML ドキュメント ハンドル (idoc)
行にマップするノードを識別する XPath 式 (rowpattern)
生成する行セットの説明
行セット列と XML ノード間のマッピング
XML ドキュメント ハンドル (idoc)
ドキュメント ハンドルは、 sp_xml_preparedocument
ストアド プロシージャによって返されます。
処理するノードを識別する XPath 式 (行パターン)
行パターンとして指定された XPath 式は、XML ドキュメント内のノードのセットを識別します。 行パターンによって識別される各ノードは、OPENXML によって生成される行セット内の 1 つの行に対応します。
XPath 式で識別されるノードには、XML ドキュメント内の任意の XML ノードを指定できます。 行パターンが XML ドキュメント内の要素のセットを識別する場合、識別された要素ノードごとに行セットに 1 つの行があります。 たとえば、 行パターン が属性で終わる場合、 rowpattern によって選択された属性ノードごとに行が作成されます。
生成する行セットの説明
OPENXML は、結果の行セットを生成するために行セット スキーマを使用します。 行セット スキーマを指定する場合は、次のオプションを使用できます。
エッジ テーブル形式の使用
エッジ テーブル形式を使用して、行セット スキーマを指定する必要があります。 WITH 句は使用しないでください。
これを行うと、OPENXML はエッジ テーブル形式の行セットを返します。 これはエッジ テーブルと呼ばれます。これは、解析された XML ドキュメント ツリー内のすべてのエッジが行セット内の行にマップされるためです。
エッジ テーブルは、きめ細かな XML ドキュメント構造を 1 つのテーブル内で表します。 この構造体には、要素名と属性名、ドキュメント階層、名前空間、および処理命令が含まれます。 エッジ テーブル形式を使用すると、メタプロパティによって公開されない追加情報を取得できます。 メタプロパティの詳細については、「 OPENXML でのメタプロパティの指定」を参照してください。
エッジ テーブルによって提供される追加情報を使用すると、要素と属性のデータ型、およびノードの種類を格納および照会したり、XML ドキュメント構造に関する情報を格納および照会したりできます。 この追加情報を使用して、独自の XML ドキュメント管理システムを構築することもできます。
エッジ テーブルを使用すると、XML ドキュメントをバイナリ ラージ オブジェクト (BLOB) 入力として受け取り、エッジ テーブルを生成し、ドキュメントをより詳細なレベルで抽出して分析するストアド プロシージャを記述できます。 この詳細レベルには、ドキュメント階層の検索、要素と属性の名前、名前空間、および処理命令が含まれます。
エッジ テーブルは、他のリレーショナル形式へのマッピングが論理的ではなく、ntext フィールドが十分な構造情報を提供していない場合に、XML ドキュメントのストレージ形式として機能することもできます。
XML パーサーを使用して XML ドキュメントを調べることができる場合は、代わりにエッジ テーブルを使用して同じ情報を取得できます。
次の表では、エッジ テーブルの構造について説明します。
列名 | データの種類 | 説明 |
---|---|---|
ID | bigint | ドキュメント ノードの一意の ID です。 ルート要素の ID 値は 0 です。 負の ID 値は予約されています。 |
parentid | bigint | ノードの親を識別します。 この ID で識別される親が必ずしも親要素であるとは限りません。 ただし、これは、親がこの ID で識別されるノードの NodeType に依存します。 たとえば、ノードがテキスト ノードの場合、その親は属性ノードである可能性があります。 ノードが XML ドキュメントの最上位にある場合、その ParentID は NULL です。 |
ノードの種類 | int | ノードの種類を識別し、XML オブジェクト モデル (DOM) ノード型の番号付けに対応する整数です。 ノードの種類を示すためにこの列に表示できる値を次に示します。 1 = 要素ノード 2 = 属性ノード 3 = テキスト ノード 4 = CDATA セクション ノード 5 = エンティティ参照ノード 6 = エンティティ ノード 7 = 処理命令ノード 8 = コメント ノード 9 = ドキュメント ノード 10 = [ドキュメントの種類] ノード 11 = ドキュメント フラグメント ノード 12 = 表記ノード 詳細については、Microsoft XML (MSXML) SDK の「nodeType プロパティ」トピックを参照してください。 |
localname | nvarchar(max) | 要素または属性のローカル名を指定します。 DOM オブジェクトに名前がない場合は NULL です。 |
接頭辞 | nvarchar(max) | ノード名の名前空間プレフィックスです。 |
namespaceuri | nvarchar(max) | ノードの名前空間 URI です。 値が NULL の場合、名前空間は存在しません。 |
datatype | nvarchar(max) | 要素または属性行の実際のデータ型であり、それ以外の場合は NULL です。 データ型は、インライン DTD またはインライン スキーマから推論されます。 |
前 | bigint | 前の兄弟要素の XML ID です。 前の兄弟が直接存在しない場合は NULL です。 |
テキスト | エヌテキスト | 属性値または要素の内容をテキスト形式で格納します。 または、エッジ テーブル エントリに値が必要ない場合は NULL です。 |
WITH 句を使用して既存のテーブルを指定する
WITH 句を使用して、既存のテーブルの名前を指定できます。 これを行うには、OPENXML が行セットを生成するためにスキーマを使用できる既存のテーブル名を指定するだけです。
WITH 句を使用してスキーマを指定する
WITH 句を使用して、完全なスキーマを指定できます。 行セット スキーマを指定する際に、列名、データ型、および XML ドキュメントへのマッピングを指定します。
SchemaDeclaration で ColPattern パラメーターを使用して、列パターンを指定できます。 指定された列パターンは、行セット列を、行パターンによって識別される XML ノードにマップするために使用され、マッピングの種類を決定するためにも使用されます。
列に ColPattern が指定されていない場合、行セット列は、 flags パラメーターで指定されたマッピングに基づいて、同じ名前の XML ノードにマップされます。 ただし、WITH 句のスキーマ仕様の一部として ColPattern が指定されている場合は、 flags パラメーターで指定されているマッピングが上書きされます。
行セット列と XML ノード間のマッピング
OPENXML ステートメントでは、必要に応じて、行セット列と行 パターンで識別される XML ノードとの間のマッピングの種類 (属性中心や要素中心など) を指定できます。 この情報は、XML ノードと行セット列の間の変換で使用されます。
マッピングは 2 つの方法で指定できます。また、両方を指定することもできます。
flags パラメーターを使用する
flags パラメーターで指定されたマッピングは、XML ノードが同じ名前の対応する行セット列にマップされる名前対応を前提としています。
ColPattern パラメーターを使用する
XPath 式である ColPattern は、WITH 句の SchemaDeclaration の一部として指定されます。 ColPattern で指定されたマッピングは、flags パラメーターで指定されたマッピングを上書きします。
ColPattern を使用して、 フラグによって示される既定のマッピングを上書きまたは拡張する、属性中心や要素中心などのマッピングの種類を指定できます。
ColPattern は、次の状況で指定されます。
行セット内の列名は、マップ先の要素名または属性名とは異なります。 この場合、 ColPattern を使用して、行セット列がマップされる XML 要素と属性名を識別します。
メタプロパティ属性を列にマップする場合。 この場合、 ColPattern を使用して、行セット列がマップされるメタプロパティを識別します。 メタプロパティの使用方法の詳細については、「 OPENXML でメタプロパティを指定する」を参照してください。
フラグと ColPattern パラメーターはどちらも省略可能です。 マッピングが指定されていない場合は、属性中心のマッピングが想定されます。 属性中心のマッピングは、 flags パラメーターの既定値です。
属性中心のマッピング
OPENXML の flags パラメーターを 1 (XML_ATTRIBUTES) に設定すると、 属性中心の マッピングが指定されます。 flagsがXML_ATTRIBUTESを含む場合、公開された行セットは、各XML要素が行として表される行を提供または消費します。 XML 属性は、SchemaDeclaration で定義されている属性、または WITH 句の Tablename によって提供される属性に、名前の対応に基づいてマップされます。 名前の対応付けとは、特定の名前の XML 属性が、同じ名前の行セット内の列に格納されることを意味します。
列名がマップ先の属性名と異なる場合は、 ColPattern を指定する必要があります。
XML 属性に名前空間修飾子がある場合、行セット内の列名にも修飾子が必要です。
要素中心のマッピング
OPENXML の flags パラメーターを 2 (XML_ELEMENTS) に設定すると、 要素中心 のマッピングが指定されます。 次の違いを除き、 属性中心 のマッピングに似ています。
マッピング例の名前の対応付けでは、列レベルのパターンが指定されていない限り、同じ名前の XML 要素への列マッピングによって非複合サブ要素が選択されます。 取得プロセスで、サブ要素に追加のサブ要素が含まれているためにサブ要素が複雑な場合、列は NULL に設定されます。 その後、サブ要素の属性値は無視されます。
同じ名前の複数のサブ要素の場合、最初のノードが返されます。
こちらもご覧ください
sp_xml_preparedocument (Transact-SQL)sp_xml_removedocument (Transact-SQL)OPENXML (Transact-SQL)XML データ (SQL Server)