ODP.NETでは、リレーショナル表およびオブジェクト・リレーショナル表やビューからXML文書としてデータを抽出できます。XML文書の使用により、データベースへの挿入、更新および削除もできます。Oracle Databaseは、データベースでのXML、Oracle XML DBの使用、高パフォーマンスなXML記憶域および取得に関連する技術の個別のグループにネイティブに対応しています。Oracle XML DBは、データベースを発展させたものであり、相互運用方式でSQLおよびXMLデータ・モデルの両方を包含しているため、従来のXMLをサポートできます。
ODP.NETにおけるXMLのサポートに関するサンプルは、次のディレクトリを参照してください。
ORACLE_BASE\ORACLE_HOME\ODP.NET\Samples
この項は次の項目で構成されています。
ODP.NETにおけるXMLのサポートでは、次の機能が提供されます。
XMLデータをそのままの形で、ネイティブなOracle Database型であるXMLTypeとして、データベースに格納します。
Oracle DatabaseインスタンスからMicrosoft .NET環境へ、XMLデータとしてリレーショナル・データおよびオブジェクト・リレーショナル・データにアクセスし、Microsoft .NET Frameworkを使用してXMLを処理します。
XMLデータを使用してデータベースに変更を保存します。
.NETアプリケーション開発者を対象として、これらの機能には次のものが含まれます。
OracleCommand、OracleConnectionおよびOracleDataReaderクラスの拡張機能。
次のXML固有のクラス。
OracleXmlType
OracleXmlTypeオブジェクトは、Oracle固有のXMLTypeデータの取得に使用されます。
OracleXmlStream
OracleXmlStreamオブジェクトは、OracleXmlTypeオブジェクトからXMLデータを読取り専用の.NET Streamオブジェクトとして取得する際に使用されます。
OracleXmlQueryProperties
OracleXmlQueryPropertiesオブジェクトは、XmlCommandTypeプロパティがQueryである場合に、OracleCommandクラスにより使用されるXMLプロパティを表します。
OracleXmlSaveProperties
OracleXmlSavePropertiesオブジェクトは、XmlCommandTypeプロパティがInsert、UpdateまたはDeleteである場合に、OracleCommandクラスにより使用されるXMLプロパティを表します。
|
関連項目: |
ODP.NETでは、Oracle Database 10gリリース2(10.2)から、SQL/XML機能、XMLQueryおよびXMLTableのネイティブ実装により、XQuery言語がサポートされます。XQuery文を実行すると、通常Oracle XML DBはXQuery式を関連する問合せとして同じベース構造にコンパイルし値を求めます。問合せは最適化され、リレーショナル・データベースおよびXQuery固有の最適化技術の両方を活用して、Oracle XML DBはネイティブのXQueryエンジンとして動作します。すべてのXQuery式の処理は、ネイティブでコンパイルされたか、または関数的に値を求めたかにかかわらず透過的であり、プログラマはXQuery最適化の利点を活かすためにこれらのコードを変更する必要はありません。
|
関連項目: OracleのXQueryサポートの詳細は、Oracle XML DB開発者ガイドを参照 |
OracleXmlTypeクラスの読取り専用のConnectionプロパティは、OracleXmlTypeクラスのインスタンス化に使用されるOracleConnectionオブジェクトへの参照を保持します。
OracleXmlTypeオブジェクトがOracleConnectionオブジェクトへの参照を取得する方法は、OracleXmlTypeクラスがインスタンス化される方法に応じて異なります。
GetOracleXmlTypeメソッド、GetOracleValueメソッドまたはGetOracleValuesメソッドを使用してOracleDataReaderクラスからインスタンス化された場合
Connectionプロパティは、OracleDataReaderオブジェクトにより使用される同じOracleConnectionオブジェクトへの参照によって設定されます。
OracleConnection型のいずれかのパラメータにより、OracleXmlTypeコンストラクタを起動してインスタンス化された場合
Connectionプロパティは、コンストラクタに指定された同じOracleConnectionオブジェクトへの参照によって設定されます。
OracleXmlType(OracleClob)コンストラクタを起動してインスタンス化された場合
Connectionプロパティは、OracleClobオブジェクトにより使用されるOracleConnectionオブジェクトへの参照によって設定されます。
ある接続に関連付けられたOracleXmlTypeオブジェクトは、別の接続に使用できません。たとえば、あるOracleXmlTypeオブジェクトがOracleConnection Aを使用して取得される場合、そのOracleXmlTypeオブジェクトはOracleConnection Bを使用するコマンドの入力パラメータとして使用できません。アプリケーションは、OracleXmlTypeオブジェクトのConnectionプロパティをチェックすることで、OracleXmlTypeオブジェクトが、その接続プロパティで参照されるOracleConnectionのコンテキスト内でのみ使用されることを保証できます。それ以外の場合、ODP.NETでは例外が発生します。
XMLType列の更新には、トランザクションは必要ありません。ただし、データベースの更新プロセス全体をトランザクション内にカプセル化することをお薦めします。これにより、エラーが発生した場合に更新をロールバックできます。
データベース内のXMLType列をOracle Data Provider for .NETを使用して更新するには、次のように複数の方法があります。
XMLType列がDataSetにフェッチされた場合、XMLTypeデータは.NET Stringとして表されます。
DataSet内のXMLTypeデータの変更には、特別な処理は必要ありません。XMLTypeデータは、DataSetに格納されたデータと同様に変更できます。変更が加えられ、OracleDataAdapter.Updateメソッドが起動されると、OracleDataAdapterオブジェクトにより、XMLTypeデータが確実に正しく処理されます。OracleDataAdapterオブジェクトでは、提供されているカスタムSQL文のINSERT、UPDATEまたはDELETEが使用されます。それ以外の場合は、データベースへの変更をフラッシュする際に、必要に応じてOracleCommandBuilderオブジェクトにより有効なSQL文が生成されます。
OracleCommandクラスは、特にOracleParameterオブジェクトの使用により、XMLTypeデータを更新するための強力な手段となります。データベース表内の列を更新するには、列の新しい値をコマンドの入力パラメータとして渡すことができます。
データベース内のXMLType列を更新するには、静的な値を使用してSQL文を実行できます。さらに、入力パラメータをSQL文、無名PL/SQLブロックまたはストアド・プロシージャにバインドし、XMLType列を更新できます。パラメータ値は、.NET Frameworkタイプ、ODP.NETタイプまたはOracleXmlTypeオブジェクトとして設定できます。
XMLType列はOracleXmlTypeオブジェクトを使用して更新できますが、OracleXmlTypeクラスのインスタンスを保持していても、データベース内のXMLType列を更新できることが保証されるわけではありません。
アプリケーションでは、次のように入力バインドを使用する方法または使用しない方法で、データベース内のXMLType列をNULL値に設定できます。
入力バインドによるXMLType列内のNULL値の設定
XMLType列をNULLに設定するには、アプリケーションにより、値がDBNull.Valueである入力パラメータをバインドできます。これによって、OracleCommandオブジェクトに対し、NULL値が挿入されることが示されます。
NULLのOracleXmlTypeオブジェクトを入力パラメータとして渡した場合、XMLType列にNULLが挿入されません。この場合、OracleCommandオブジェクトでは例外が発生します。
入力バインドを使用しないXMLType列内のNULL値の設定
次の例では、入力バインドを使用せずにXMLType列でNULL値を設定する方法を示しています。
// Create a table with an XMLType column in the database CREATE TABLE XML_TABLE(NUM_COL number, XMLTYPE_COL xmltype);
アプリケーションでは、明示的にNULLを挿入するか、または次の例のようにXMLType列になにも挿入しないことで、この列にNULL値を設定できます。
insert into xml_table(xmltype_col) values(NULL);
update xml_table t set t.xmltype_col=NULL;
OracleXmlTypeオブジェクトでXMLデータを更新するには、複数の方法があります。
OracleXmlTypeオブジェクトのUpdateメソッドにXPATH式および新しい値を渡すことで、XMLデータを更新できます。
XMLデータは、OracleXmlTypeオブジェクトのGetXmlDocumentメソッドを使用して、.NET FrameworkのXmlDocumentオブジェクトとしてクライアント側で取得できます。このため、このXMLデータは適切な.NET Frameworkクラスを使用して操作できます。.NET Frameworkクラスから、更新されたXMLデータにより新規のOracleXmlTypeを作成できます。この新規のOracleXmlTypeは、入力パラメータとしてUPDATE文またはINSERT文にバインドされます。
表3-18の次の文字は、XMLでは特殊な意味を持ちます。詳細は、XML 1.0の仕様を参照してください。
表3-18 XMLの特殊文字
| 特殊文字 | XMLでの意味 | 実体エンコード |
|---|---|---|
|
< |
XMLタグの開始 |
< |
|
> |
XMLタグの終了 |
> |
|
" |
引用符 |
" |
|
' |
アポストロフィまたは一重引用符 |
' |
|
& |
アンパサンド |
& |
これらの文字がXML要素内のデータとして使用されている場合、対応する実体エンコードに置き換えられます。
また、XML要素名では特定の文字が無効です。SQL識別子(列名など)がXML要素名にマップされている場合、これらの文字は、Unicodeの文字エンコードから導出された一連の16進数字に変換され、前置きのアンダースコア、小文字のxおよび後続のアンダースコアで囲まれます。空白はXML要素名では有効な文字ではありません。SQL識別子に空白文字が含まれる場合、対応するXML要素名において、空白文字が_x0020_に置き換えられます。これは、空白文字のUnicodeエンコードに基づいています。
この項では、SQL問合せから結果セットをXMLデータ形式で取得する方法について説明します。
表3-19では、異なるデータベース・リリースにおける、データ取得時の日時書式の処理をリストしています。
表3-19 データ取得時の日時書式の処理
| データベース・リリース | サポートされる日時書式 |
|---|---|
|
Oracle9iリリース2(9.2.x)およびOracle Database 10g |
Oracle
結果として得られたXML文書を使用して、データベースに変更を保存する場合は、すべての このためには、問合せを実行する前に、アプリケーションで、セッションにおける次のNLSセッション・パラメータについて、
|
|
Oracle Database 10gリリース2(10.2)以上 |
生成されたXMLの XML Schema仕様の詳細は、次のURLを参照してください。
|
問合せ内の選択リスト列のいずれかにあるデータに、XMLの特殊文字が含まれている場合(表3-18を参照)、結果であるXML文書では、これらの文字は対応する実体エンコードに置き換えられます。
次の例では、ODP.NETで列データ内の山カッコの特殊文字が処理される方法を示しています。
/* Database Setup
connect scott/tiger@oracle
drop table specialchars;
create table specialchars ("id" number, name varchar2(255));
insert into specialchars values (1, '<Jones>');
commit;
*/
// C#
using System;
using System.Data;
using System.Xml;
using Oracle.DataAccess.Client;
class QueryResultAsXMLSample
{
static void Main()
{
OracleConnection con = new OracleConnection();
con.ConnectionString = "User Id=scott;Password=tiger;Data Source=oracle;";
con.Open();
// Create the command
OracleCommand cmd = new OracleCommand("", con);
// Set the XML command type to query.
cmd.XmlCommandType = OracleXmlCommandType.Query;
// Set the SQL query
cmd.CommandText = "select * from specialchars";
// Set command properties that affect XML query behavior.
cmd.BindByName = true;
// Set the XML query properties
cmd.XmlQueryProperties.MaxRows = -1;
// Get the XML document as an XmlReader.
XmlReader xmlReader = cmd.ExecuteXmlReader();
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.PreserveWhitespace = true;
xmlDocument.Load(xmlReader);
Console.WriteLine(xmlDocument.OuterXml);
// Close and Dispose OracleConnection object
con.Close();
con.Dispose();
}
}
この表に対して次のXML文書が生成されます。山カッコを表すXML実体エンコードは太字で表記されます。
<?xml version = '1.0'?>
<ROWSET>
<ROW>
<id>1</id >
<NAME><Jones></NAME>
</ROW>
</ROWSET>
表名またはビュー名に英数字以外の文字(アンダースコア(_)を除く)が含まれる場合、この表名またはビュー名は引用符で囲む必要があります。
たとえば、名前がtest'ingの表からすべてのエントリを選択するには、OracleCommandオブジェクトのCommandTextプロパティを次の文字列に設定する必要があります。
"select * from \"test'ing\"";
SQL識別子(列名)とXML要素名のマッピングは大/小文字が区別され、要素名は表またはビューの列名と大/小文字がまったく同じになります。
ただし、ルート・タグ名および行タグ名は大/小文字が区別されません。次の例では、この場合の大/小文字区別を示しています。
//Create the following table
create table casesensitive_table ("Id" number, NAME varchar2(255));
//insert name and id
insert into casesensitive_table values(1, 'Smith');
次のXML文書が生成されます。
<?xml version = '1.0'?>
<ROWSET>
<ROW>
<Id>1</Id>
<NAME>Smith</NAME>
</ROW>
</ROWSET>
Id列の要素名の大/小文字が列名と一致する点に注意してください。
SQL問合せにより生成された行ごとに、SQL識別子(列名)が、生成されたXML文書内のXML要素にマップされます。
// Create the following table create table emp_table (EMPLOYEE_ID NUMBER(4), LAST_NAME varchar2(25)); // Insert some data insert into emp_table values(205, 'Higgins');
SELECT * FROM EMP_TABLEというSQL問合せにより、次のXML文書が生成されます。
<?XML version="1.0"?>
<ROWSET>
<ROW>
<EMPLOYEE_ID>205</EMPLOYEE_ID>
<LAST_NAME>Higgins</LAST_NAME>
</ROW>
</ROWSET>
employees表のEMPLOYEE_IDおよびLAST_NAMEデータベース列は、生成されたXML文書のEMPLOYEE_ID要素およびLAST_NAME要素にマップされます。
この項では、データベースからXMLとして問合せ結果を取得する場合に、Oracle DatabaseでSQL識別子のXML要素名へのマッピングを処理する方法について説明します。デモでは、some id列を含むspecialchars表を使用します。
// Create the specialchars table
create table specialchars ("some id" number, name varchar2(255));
specialchars表には、空白文字が含まれるsome id列がある点に注意してください。XML要素名では、空白文字は使用できません。
問合せ結果をXMLで取得する場合、問合せの選択リスト内のSQL識別子には、XML要素名で無効となる文字を使用できます。これらのSQL識別子(列名など)がXML要素名にマップされている場合、これらの各文字は、Unicodeの文字エンコードから導出された一連の16進数字に変換され、前置きのアンダースコア、小文字のxおよび後続のアンダースコアで囲まれます。
このため、次の例のSQL問合せを使用して、specialchars表から結果をXML文書で取得できます。
select "some id", name from specialchars;
次の方法でXML要素名へのSQL識別子のデフォルト・マッピングを修正できます。
ソースを変更します。ソース・スキーマ上にオブジェクト・リレーショナル・ビューを作成し、このビューを新規ソースにします。
SQL問合せでカーソル副問合せおよびキャスト多重集合構造を使用します。
SQL問合せで列名または属性名の別名を作成します。別名にアットマーク(@)を付加し、別名をXML要素ではなくXML属性にマップします。
XML文書を変更します。Extensible Stylesheet Language Transformation(XSLT)を使用してXML文書を変換します。XSL文書およびパラメータを指定します。リレーショナル・データからXML文書が生成された後、変換が自動的に実行されます。これはパフォーマンスに影響する可能性があります。
XML文書で使用されるルート・タグおよび行タグの名前を指定します。
ODP.NETでは、オブジェクト・リレーショナル列、表およびビューに格納されたデータについて、XML文書を生成できます。
// Create the following tables and types
CREATE TYPE "EmployeeType" AS OBJECT (EMPNO NUMBER, ENAME VARCHAR2(20));
/
CREATE TYPE EmployeeListType AS TABLE OF "EmployeeType";
/
CREATE TABLE mydept (DEPTNO NUMBER, DEPTNAME VARCHAR2(20),
EMPLIST EmployeeListType)
NESTED TABLE EMPLIST STORE AS EMPLIST_TABLE;
INSERT INTO mydept VALUES (1, 'depta',
EmployeeListType("EmployeeType"(1, 'empa')));
この表に対して次のXML文書が生成されます。
<?xml version = "1.0"?>
<ROWSET>
<ROW>
<DEPTNO>1</DEPTNO>
<DEPTNAME>depta</DEPTNAME>
<EMPLIST>
<EmployeeType>
<EMPNO>1</EMPNO>
<ENAME>empa</ENAME>
</EmployeeType>
</EMPLIST>
</ROW>
</ROWSET>
ODP.NETでは、コレクション要素内の各項目が、コレクション内の要素のデータベース型名で囲まれます。mydept表にはEMPLISTデータベース列にコレクションがあり、このコレクション内の各項目はEmployeeType型です。このため、XML文書では、例に太字で表されるように、コレクション内の各項目が型名EmployeeTypeで囲まれます。
この項では、XMLを使用してデータベースのデータに変更を加える方法について説明します。
表3-20では、異なるデータベース・リリースにおけるデータ保存時の日時書式の処理をリストしています。
表3-20 データ保存時の日時書式の処理
| データベース・リリース | サポートされる日時書式 |
|---|---|
|
Oracle9iリリース2(9.2.x)およびOracle Database 10g |
次の文字列は、Oracle日時書式表記法( XML文書にISO書式表記法を使用するだけでなく、保存を実行する前に、アプリケーションで、セッションにおける次のNLSセッション・パラメータについて、
|
|
Oracle Database 10gリリース2(10.2)以上 |
生成されたXMLの XML Schema仕様の詳細は、次のURLを参照してください。
|
XMLデータを使用して、データベース表およびビューに変更を保存できます。ただし、挿入、更新および削除の操作は、単一のXML文書では組み合せることができません。ODP.NETでは、単一のXML文書を受け入れて、どの変更が挿入、更新または削除のいずれであるかを判別できません。
挿入変更では挿入する行、更新変更では更新する行、削除変更では削除する行のみが含まれるXML文書である必要があります。
たとえば、HRサンプル・スキーマに付属するemployees表を使用して、次の問合せを指定できます。
select employee_id, last_name from employees where employee_id = 205;
次のXML文書が生成されます。
<?xml version = '1.0'?>
<ROWSET>
<ROW>
<EMPLOYEE_ID>205</EMPLOYEE_ID>
<LAST_NAME>Higgins</LAST_NAME>
</ROW>
</ROWSET>
従業員205の名前をHigginsからSmithに変更するには、employees表および変更が含まれるXMLデータを次のように指定します。
<?xml version = '1.0'?>
<ROWSET>
<ROW>
<EMPLOYEE_ID>205</EMPLOYEE_ID>
<LAST_NAME>Smith</LAST_NAME>
</ROW>
</ROWSET>
XML文書内のいずれかの要素内のデータに、XMLの特殊文字が含まれている場合(表3-18を参照)、そのデータがデータベース表列に正しく格納されるためには、XML文書で、これらの文字を適切な実体エンコードに置き換えるか、エスケープ文字で上書きする必要があります。そうしないと、ODP.NETは例外をスローします。
次の例では、ODP.NETで実体エンコードを使用して列データ内の山カッコの特殊文字が処理される方法を示しています。
// Create the following table
create table specialchars ("id" number, name varchar2(255));
次のXML文書を使用して、値(1、<Jones>)をspecialchars表に挿入できます。山カッコを表すXML実体エンコードは太字で表記されます。
<?xml version = '1.0'?> <ROWSET> <ROW> <id>1</id > <NAME><Jones></NAME> </ROW> </ROWSET>
表名またはビュー名に英数字以外の文字(アンダースコア(_)を除く)が含まれる場合、この表名またはビュー名は引用符で囲む必要があります。
たとえば、名前がtest'ingの表に変更を保存するには、OracleCommand.XmlSaveProperties.TableNameプロパティを"\"test'ing\""に設定する必要があります。
XML文書内のデータ行を表すXML要素ごとに、子XML要素がデータベース列名にマップされます。子要素名と列名のマッピングでは常に大/小文字が区別されますが、ルート・タグ名および行タグ名では区別されません。この大/小文字区別の例を次に示します。
//Create the following table
create table casesensitive_table ("Id" number, NAME varchar2(255));
次のXML文書を使用して、値(1、Smith)をcasesensitive_tableに挿入できます。
<?xml version = '1.0'?>
<ROWSET>
<ROW>
<Id>1</Id>
<NAME>Smith</NAME>
</ROW>
</ROWSET>
Id列の要素名の大/小文字が列名と一致する点に注意してください。
この項では、データベースでデータ操作にXMLを使用する場合に、Oracle Databaseで列名へのXML要素名のマッピングを処理する方法について説明します。次にsome id列を含むspecialchars表を使用する処理を示します。
// Create the specialchars table
create table specialchars ("some id" number, name varchar2(255));
specialchars表には、空白文字が含まれるsome id列がある点に注意してください。XML要素名では、空白文字は使用できません。
XML文書を使用して表またはビューに変更を保存する場合、OracleCommand.XmlSaveProperties.UpdateColumnsListを使用して、更新または挿入する列のリストを指定します。
XML文書を使用して表またはビュー内の列の変更を保存する場合で、対応する列名にXML要素名では無効となる文字が含まれる場合、次の例のように、UpdateColumnsListプロパティにエスケープした列名を指定する必要があります。
次のXML文書を使用して、値(2、<Jones>)をspecialchars表に挿入できます。
<?xml version = '1.0'?>
<ROWSET>
<ROW>
<some_x0020_id>2</some_x0020_id>
<NAME><Jones></NAME>
</ROW>
</ROWSET>
次のコード例は、更新または挿入する列のリストを指定します。
/* Database Setup
connect scott/tiger@oracle
drop table specialchars;
create table specialchars ("some id" number, name varchar2(255));
insert into specialchars values (1, '<Jones>');
commit;
*/
// C#
using System;
using System.Data;
using System.Xml;
using Oracle.DataAccess.Client;
class InsertUsingXmlDocSample
{
static void Main()
{
OracleConnection con = new OracleConnection();
con.ConnectionString = "User Id=scott;Password=tiger;Data Source=oracle;";
con.Open();
Console.WriteLine("Connected Successfully");
// Create the command
OracleCommand cmd = new OracleCommand("", con);
// Set the XML command type to query.
cmd.XmlCommandType = OracleXmlCommandType.Insert;
// Set the XML document
cmd.CommandText = "<?xml version = '1.0'?>\n" + "<ROWSET>\n" + "<ROW>\n" +
"<some_x0020_id>2</some_x0020_id>\n" + "<NAME><Jones></NAME>\n" +
"</ROW>\n" + "</ROWSET>\n";
cmd.XmlSaveProperties.Table = "specialchars";
string[] ucols = new string[2];
ucols[0] = "some_x0020_id";
ucols[1] = "NAME";
cmd.XmlSaveProperties.UpdateColumnsList = ucols;
// Insert rows
int rows = cmd.ExecuteNonQuery();
Console.WriteLine("Number of rows inserted successfully : {0} ", rows);
// Close and Dispose OracleConnection object
con.Close();
con.Dispose();
}
}
XML文書の変更は、オブジェクト・リレーショナル・データにも保存できます。コレクション内の各項目は、XML文書に次のいずれかの方法で指定できます。
項目のデータベース型名をXML要素名として囲みます。
_ITEMがXML要素名として追加されたコレクションを保持するデータベース列名を囲みます。