XML データのインスタンスの作成

適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

この記事では、XML インスタンスを生成する方法について説明します。

SQL Server では、次の方法で XML インスタンスを生成できます。

  • 文字列インスタンスの型をキャストする。

  • FOR XML 句を指定した SELECT ステートメントを使用する。

  • 定数の代入を使用する。

  • 一括読み込みを使用する。

文字列とバイナリ インスタンスの型キャスト

[ n][var]char[n] テキストvarbinaryimageなどの SQL Server の文字列データ型は、xml データ型にキャスト (CAST) または変換 (CONVERT) することにより、xml データ型に解析できます。 型指定されていない XML は、正しい形式かどうかが確認されます。 xml 型に関連付けられたスキーマがある場合は、検証も行われます。 詳細については、「 型指定された XML と型指定されていない XML の比較」を参照してください。

XML ドキュメントは、UTF-8、UTF-16、windows-1252 など、さまざまなエンコードを使用してエンコードできます。 ここでは、文字列およびバイナリの元のデータ型と XML ドキュメントのエンコード間の相互作用における規則、およびパーサーの動作に関する規則を概説します。

nvarchar 型は UTF-16 や UCS-2 などの 2 バイト Unicode エンコードを想定しているので、XML パーサーは文字列値を 2 バイト Unicode でエンコードされた XML ドキュメントまたは XML フラグメントとして処理します。 つまり、XML ドキュメントには、元のデータ型との互換性だけでなく、2 バイト Unicode エンコードでのエンコードも必要であるということになります。 UTF-16 でエンコードされた XML ドキュメントでは、UTF-16 バイト オーダー マーク (BOM) を指定できますが、指定する必要はありません。これは、変換元データ型のコンテキストにより、2 バイト Unicode でエンコードされたドキュメントに限定されることが明確であるためです。

varchar 文字列の内容は、XML パーサーによって、1 バイトでエンコードされた XML ドキュメントまたは XML フラグメントとして扱われます。 varchar の変換元文字列にはコード ページが関連付けられているので、明示的なエンコード方法が XML 自体に指定されていない場合、XML パーサーはそのコード ページを使用してエンコードを行います。XML インスタンスに BOM またはエンコード宣言がある場合、このコード ページとの一貫性が必要になります。そうでない場合、XML パーサーからエラーが報告されます。

varbinary の内容は、XML パーサーに直接渡されるコードポイント ストリームとして処理されます。 このため、XML ドキュメントまたは XML フラグメントに、BOM またはその他のエンコード情報をインラインで指定する必要があります。 XML パーサーは、ストリームからのみエンコード方法を判断します。 つまり、UTF-16 でエンコードされた XML には UTF-16 BOM を指定する必要があり、BOM やエンコード宣言のない XML インスタンスは UTF-8 として解釈されます。

XML ドキュメントのエンコードが事前にわからないために、XML にキャストする前に XML データではなく文字列データまたはバイナリ データとしてデータが渡される場合は、そのデータを varbinaryとして処理することをお勧めします。 たとえば、OpenRowset() を使用して XML ファイルからデータを読み取る場合、次のように、そのデータを varbinary(max) 値として読み取るように指定してください。

SELECT CAST(x AS XML);
FROM OpenRowset(BULK 'filename.xml', SINGLE_BLOB) R(x);

SQL Server 内部では、UTF-16 エンコードを使用した効率のよいバイナリ表記で XML が表現されます。 ユーザーが指定したエンコードは保持されませんが、解析処理時に考慮されます。

CLR ユーザー定義型の型キャスト

CLR ユーザー定義型で XML シリアル化を指定している場合は、その型のインスタンスを XML データ型に明示的にキャストすることができます。 CLR ユーザー定義型の XML シリアル化の詳細については、「CLR データベース オブジェクトからの XML シリアル化」を参照してください。

型指定された XML の空白の処理

SQL Server では、要素の内容に含まれる空白文字は、開始タグや終了タグなどのマークアップで区切られた空白文字だけのシーケンス内に出現し、エンティティに変換されていない場合、重要でないと見なされます (CDATA セクションは無視されます)。この空白文字の処理は、W3C (World Wide Web Consortium) から公開されている XML 1.0 仕様の空白文字に関する記述とは異なります。 これは、SQL Server の XML パーサーが XML 1.0 の定義に従って、限定された数の DTD サブセットしか認識しないためです。 SQL Server でサポートされる限定された DTD サブセット数の詳細については、「CAST および CONVERT (Transact-SQL)」を参照してください。

XML パーサーは、既定では、文字列データを XML に変換するときに、次のいずれかの条件に当てはまる場合は、重要ではない空白文字を破棄します。

  • xml:space 属性が、要素またはその先祖の要素で定義されていない。

  • 要素またはその先祖の要素の 1 つで有効になっている xml:space 属性に既定値が設定されている。

次に例を示します。

DECLARE @x XML;
SET @x = '<root>      <child/>     </root>';
SELECT @x;

結果を次に示します。

<root><child/></root>

ただし、この動作は変更できます。 xml DT インスタンスの空白文字を保持するには、CONVERT 演算子を使用し、省略可能な style パラメーターを値 1 に設定します。 次に例を示します。

SELECT CONVERT(xml, N'<root>      <child/>     </root>', 1);

style パラメーターが使用されていないか、この値が 0 に設定されていると、xml DT インスタンスの変換では重要でない空白文字は保持されません。 文字列データを xml DT インスタンスに変換するときの、CONVERT 演算子と style パラメーターの使用方法の詳細については、「CAST および CONVERT (Transact-SQL)」を参照してください。

例: 型指定された XML に文字列値をキャストし、列に割り当てる

次の例では、XML フラグメントを格納した文字列変数を xml データ型にキャストし、 xml 型の列に格納します。

CREATE TABLE T(c1 int primary key, c2 xml);
GO
DECLARE  @s VARCHAR(100);
SET @s = '<Cust><Fname>Andrew</Fname><Lname>Fuller</Lname></Cust>';

次の挿入操作では、文字列から xml 型に暗黙的に変換が行われます。

INSERT INTO T VALUES (3, @s);

文字列を xml 型に明示的に cast() できます。

INSERT INTO T VALUES (3, CAST(@s AS XML));

または、次に示すように convert() を使用することもできます。

INSERT INTO T VALUES (3, CONVERT(XML, @s));

例: 型指定された XML に文字列を変換し、変数に割り当てる

次の例では、文字列を xml 型に変換し、 xml データ型の変数に割り当てます。

DECLARE @x XML;
DECLARE  @s VARCHAR(100);
SET @s = '<Cust><Fname>Andrew</Fname><Lname>Fuller</Lname></Cust>';
SET @x = CONVERT(XML, @s);
SELECT @x;

SELECT ステートメントに FOR XML 句を使用する

SELECT ステートメントに FOR XML 句を使用すると、結果を XML として返すことができます。 次に例を示します。

DECLARE @xmlDoc XML;
SET @xmlDoc = (SELECT Column1, Column2
               FROM   Table1, Table2
               WHERE  <some condition>
               FOR XML AUTO)
...;

SELECT ステートメントはテキスト形式の XML フラグメントを返します。これは、 xml データ型の変数への代入時に解析されます。

FOR XML 句で FOR XML 句の TYPE ディレクティブ を使用することもできます。その場合、FOR XML クエリの結果が直接 xml 型で返されます。

DECLARE @xmlDoc XML;
SET @xmlDoc = (SELECT ProductModelID, Name
               FROM   Production.ProductModel
               WHERE  ProductModelID = 19
               FOR XML AUTO, TYPE);
SELECT @xmlDoc;

結果を次に示します。

<Production.ProductModel ProductModelID="19" Name="Mountain-100" />...

次の例では、FOR XML クエリの型指定された xml の結果を、xml 型の列に挿入します。

CREATE TABLE T1 (c1 int, c2 xml);
GO
INSERT T1(c1, c2)
SELECT 1, (SELECT ProductModelID, Name
           FROM Production.ProductModel
           WHERE ProductModelID = 19
           FOR XML AUTO, TYPE);
SELECT * FROM T1;
GO

FOR XML の詳細については、「FOR XML (SQL Server)」を参照してください。

注意

SQL Server は、TYPE ディレクティブを使用する FOR XML クエリや、xml データ型を使用して SQL 列、変数、および出力パラメーターから XML を返す FOR XML クエリなど、異なるサーバー構成の結果として、xml データ型インスタンスをクライアントに返します。 クライアント アプリケーションのコードでは、ADO.NET プロバイダーがこの xml データ型情報をサーバーからバイナリ エンコード形式で送信するよう要求します。 ただし、TYPE ディレクティブを指定しないで FOR XML を使用した場合、XML データは文字列型のデータとして返されます。 どんな場合でも、クライアント プロバイダーは常にいずれかの形式の XML を処理できます。

定数の代入の使用

xml データ型のインスタンスが必要な場所に、文字列定数を使用できます。 これは、文字列から XML への暗黙の CAST と同じです。 次に例を示します。

DECLARE @xmlDoc XML;
SET @xmlDoc = '<Cust><Fname>Andrew</Fname><Lname>Fuller</Lname></Cust>';
-- Or
SET @xmlDoc = N'<?xml version="1.0" encoding="ucs-2"?><doc/>';

上記の例では、文字列が xml データ型に暗黙的に変換され、 xml 型の変数に代入されます。

次の例では、 xml 型の列に定数文字列を挿入します。

CREATE TABLE T(c1 INT PRIMARY KEY, c2 XML);
INSERT INTO T VALUES (3, '<Cust><Fname>Andrew</Fname><Lname>Fuller</Lname></Cust>');

注意

型指定された XML では、指定したスキーマに対して XML が検証されます。 詳細については、「 型指定された XML と型指定されていない XML の比較」を参照してください。

一括読み込みを使用する

OPENROWSET (Transact-SQL) 機能が強化され、データベースに XML ドキュメントを一括読み込みできるようになりました。 ファイルからデータベース内の xml 型の列に、XML インスタンスを一括読み込みできます。 作業用サンプルについては、「XML ドキュメントの一括インポートと一括エクスポートの例 (SQL Server)」を参照してください。 XML ドキュメントの読み込みの詳細については、「 XML データの読み込み」を参照してください。

このセクションの内容

記事 説明
XML データの取得および XML データに対するクエリの実行 XML インスタンスをデータベースに格納するときに保持されない部分について説明します。

関連項目