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

適用対象: SQL Server Azure SQL Database Azure SQL Managed Instance

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

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

  • 文字列インスタンスの型をキャストする。
  • SELECT 句を指定した FOR XML ステートメントを使用する。
  • 定数の代入を使用する。
  • 一括読み込みを使用する。

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

[n]varchar][n]char]、[n]textvarbinaryimageなどの 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 インスタンスに BOM またはエンコード宣言がある場合、BOM または宣言はコード ページと一致している必要があります。それ以外の場合、パーサーはエラーを報告します。

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

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」を参照してください。

例: 型指定された 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 句を使用する

FOR XML ステートメントに SELECT 句を使用すると、結果を 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 句の 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)」を参照してください。

Note

SQL Server は、FOR XML ディレクティブを使用したり、または xml データ型を使用してSQL Server データベース エンジンの列、変数、および出力パラメーターから XML を返す TYPE クエリなど、異なるサーバー構成の結果として、xml データ型インスタンスをクライアントに返します。 クライアント アプリケーションのコードでは、ADO.NET プロバイダーがこの xml データ型情報をサーバーからバイナリ エンコード形式で送信するよう要求します。 ただし、FOR XML ディレクティブを指定しないで TYPE を使用した場合、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>');

Note

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

一括読み込みを使用する

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

このセクションの内容

記事 説明
XML クエリ オプションと保持されるデータ XML インスタンスをデータベースに格納するときに保持されない部分について説明します。