ODP.NETでは、リレーショナル表、オブジェクト・リレーショナル表およびビューのデータをXML文書形式で抽出できます。データベースに対する挿入、更新および削除の操作にも、XML文書を使用できます。 Oracle Databaseでは、Oracle XML DBにより、データベースで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フレームワークを使用して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プロパティを表します。
参照: |
Oracle Database 10gリリース2(10.2)以降、ODP.NETは、SQL/XML関数、XMLQuery
およびXMLTable
のネイティブ実装によりXQuery言語をサポートしています。XQuery文の実行時、Oracle XML DBは通常、リレーショナル問合せと同じ基礎構造にXQuery式をコンパイルしてXQuery式を評価します。問合せは最適化され、Oracle XML DBがネイティブXQueryエンジンの役割を果たすように、リレーショナル・データベースおよびXQuery固有の最適化テクノロジの両方が活用されます。すべてのXQuery式の処理は、ネイティブ・コンパイルされているか機能上の評価が行われているかに関係なく透過的となります。つまり、プログラマはXQueryの最適化を利用するようコードを変更する必要はありません。
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フレームワーク・タイプ、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フレームワークのXmlDocument
オブジェクトとしてクライアント側で取得できます。このため、このXMLデータは適切な.NETフレームワーク・クラスを使用して操作できます。.NETフレームワーク・クラスから、更新されたXMLデータにより新規のOracleXmlType
を作成できます。この新規のOracleXmlType
は、入力パラメータとしてUPDATE文またはINSERT文にバインドされます。
表3-15に示す文字は、XMLでは特殊な意味を持ちます。詳細は、XML 1.0の仕様を参照してください。
表3-15 XMLの特殊文字
特殊文字 | XMLでの意味 | 実体エンコード |
---|---|---|
< |
XMLタグの開始 |
< |
> |
XMLタグの終了 |
> |
" |
引用符 |
" |
' |
アポストロフィまたは一重引用符 |
' |
& |
アンパサンド |
& |
これらの文字がXML要素内のデータとして使用されている場合、対応する実体エンコードに置き換えられます。
また、XML要素名では特定の文字が無効です。SQL識別子(列名など)がXML要素名にマップされている場合、これらの文字は、Unicodeの文字エンコードから導出された一連の16進数字に変換され、前置きのアンダースコア、小文字のx
および後続のアンダースコアで囲まれます。空白はXML要素名では有効な文字ではありません。SQL識別子に空白文字が含まれる場合、対応するXML要素名においては、空白文字が_x0020_
に置き換えられます。これは、Unicodeエンコードによる空白文字に基づいています。
この項では、SQL問合せから結果セットをXMLデータ形式で取得する方法について説明します。
表3-16は、各データベース・リリースにおける、データ取得時の日時書式の処理のリストです。
表3-16 データ取得時の日時書式の処理
データベース・リリース | サポートされる日時書式 |
---|---|
Oracle9i リリース2(9.2.x)およびOracle Database 10g |
Oracle
結果として得られたXML文書を使用して、データベースに変更を保存する場合は、すべての このためには、問合せを実行する前に、アプリケーションで、セッションにおける次のNLSセッション・パラメータについて、
|
Oracle Database 10gリリース2(10.2)以降 |
生成されるXMLの XMLスキーマ仕様の詳細は、次を参照してください。
|
問合せ内の選択リストの列のデータに、XMLで特殊な意味を持つ文字が含まれる場合(表3-15を参照)、これらの文字は、結果として得られる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-17は、各データベース・リリースにおける、データ保存時の日時書式の処理のリストです。
表3-17 データ保存時の日時書式の処理
データベース・リリース | サポートされる日時書式 |
---|---|
Oracle9i リリース2(9.2.x)およびOracle Database 10g |
次の文字列は、Oracle日時書式表記法( XML文書にISO書式表記法を使用するだけでなく、保存を実行する前に、アプリケーションで、セッションにおける次のNLSセッション・パラメータについて、
|
Oracle Database 10gリリース2(10.2)以降 |
生成されるXMLの XMLスキーマ仕様の詳細は、次を参照してください。
|
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-15を参照)、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を使用する場合に、XML要素名から列名へのマッピングがOracle Databaseで処理される方法について説明します。 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要素名として追加されたコレクションを保持するデータベース列の名前を囲みます。