10 XMLTypeビュー

リレーショナル・データおよびオブジェクト・リレーショナル・データに対するXMLTypeビューを作成できます。

10.1 XMLTypeビューの概要

XMLTypeビューは、既存のリレーショナル・データおよびオブジェクト・リレーショナル・データをXML形式でラップします。これにより、XMLデータを予期し、XML SchemaなどのXML機能を使用するコンテキストで既存のデータを使用できます。

XMLTypeビューを使用する主なメリットは次のとおりです。

  • 基本のレガシー・データを移行せずに、XML Schema機能を使用するOracle XML DBのXML機能を使用できます。

  • XMLTypeビューでは、様々な形式の記憶域を使用してデータを格納できます。XMLTypeとして格納するか、またはどのXMLType記憶域モデルを使用するかについて、急いで決める必要はありません。

XMLTypeビューは、オブジェクト・ビューに類似しています。XMLTypeビューの各行は、XMLTypeインスタンスに対応しています。ビュー内の各行を一意に識別するためのオブジェクト識別子は、SQL/XML関数XMLCastおよびXMLQuery()を使用して作成できます。

XMLTypeビューには2つのタイプがあります。

  • スキーマに基づかないXMLTypeビュー。これらのビューは特定のXML Schemaに準拠しません。

  • XML Schemaに基づくXMLTypeビュー。XMLType表に関して、特定のXML Schemaに準拠するXMLTypeビューは、XML Schemaに基づくXMLTypeビューと呼びます。これらのビューでは、XML Schemaに基づかないXMLTypeビューより厳密な型指定ができます。

XMLTypeビューに対する問合せのXPathリライトは、XML Schemaに基づくXMLTypeビューとXML Schemaに基づかないXMLTypeビューの両方で可能です。XPathリライトの詳細は、オブジェクト・リレーショナル記憶域のXPathリライトで説明しています。

XML Schemaに基づくXMLTypeビューを作成するには、最初にXML Schemaを登録します。ビューがオブジェクト・ビューである場合、つまりオブジェクト型を使用して構成されている場合、XML Schemaには、XMLとSQLオブジェクト型の間の双方向マッピングを表す注釈が必要です。その後、適切なSQLオブジェクト型のインスタンスを構築する基礎となる問合せを指定することによって、登録されたXML Schemaに準拠するXMLTypeビューを作成できます。

XMLTypeビューは、次のいずれかの方法で作成できます。

  • XMLElementXMLForestXMLConcatXMLAggなどのSQL/XMLパブリッシング関数に基づいて構成する方法。SQL/XMLパブリッシング関数を使用すると、XML Schemaに基づかないXMLTypeビューとXML Schemaに基づくXMLTypeビューの両方を構成できます。これによって、リレーショナル・レガシー・データをXMLに物理的に移行せずに、基礎となるリレーショナル表から直接XMLTypeビューを構成できます。ただし、XML Schemaに基づくXMLTypeビューを構成するには、XML Schemaを登録する必要があり、SQL/XMLパブリッシング関数によって生成されたXML値はXML Schemaに制限される必要があります。

  • オブジェクト型またはオブジェクト・ビューに基づく方法。これによって、リレーショナルまたはオブジェクト・リレーショナルのレガシー・データをXMLに物理的に移行せずに、基礎となるリレーショナル表またはオブジェクト・リレーショナル表から直接XMLTypeビューを構成できます。XML Schemaに基づくXMLTypeビューでは、既存のオブジェクト型へのマッピングをXML Schemaに注釈として付けるか、または既存のオブジェクト型からXML Schemaを生成する必要があります。

  • XMLType表から直接構成する方法。

10.2 XMLTypeビューのCREATE VIEW: 構文

XMLTypeビューを作成するためのCREATE VIEW句の構文を示します。

図10-1に、この構文を示します。CREATE VIEWの構文の詳細は、Oracle Database SQL言語リファレンスを参照してください。

図10-1 XMLTypeビューの作成の句: 構文

図10-1の説明が続きます
「図10-1 XMLTypeビューの作成の句: 構文」の説明

10.3 XML Schemaに基づかないXMLTypeビューの作成

XML Schemaに基づかないXMLTypeビューのXMLデータは、登録されたXML Schemaに準拠するように制約されません。XML Schemaに基づかないXMLTypeビューを作成するには、SQL/XMLパブリッシング関数を使用します。

例10-1に、SQL/XML関数XMLELementを使用してXMLTypeビューを作成する方法を示します。

リレーショナル表またはリレーショナル・ビュー内の既存のデータは、この方法を使用してXMLデータとして公開できます。ビューがSQL/XMLパブリッシング関数によって生成されると、XQuery式を使用してそのビューにアクセスする問合せは、多くの場合リライトされます。最適化された問合せは、基礎となるリレーショナル列に直接アクセスできます。詳細は、オブジェクト・リレーショナル記憶域のXPathリライトを参照してください。

XMLTypeビューに対してDML操作を行うことができますが、通常、DML操作を処理するためにINSTEAD OFトリガーを作成する必要があります。

関連項目:

SQL/XMLパブリッシング関数の詳細は、リレーショナル・データからのXMLデータの生成を参照してください。

例10-1 XMLELEMENTを使用したXMLTypeビューの作成

CREATE OR REPLACE VIEW emp_view OF XMLType
  WITH OBJECT ID (XMLCast(XMLQuery('/Emp/@empno'
                                   PASSING OBJECT_VALUE RETURNING CONTENT)
                          AS BINARY_DOUBLE)) AS
  SELECT XMLElement("Emp",
                    XMLAttributes(employee_id AS "empno"),
                    XMLForest(e.first_name ||' '|| e.last_name AS "name",
                              e.hire_date AS "hiredate"))
    AS "result" FROM employees e WHERE salary > 15000;

SELECT * FROM emp_view;
 
SYS_NC_ROWINFO$
-------------------------------------------------------------------------------------
<Emp empno="100"><name>Steven King</name><hiredate>2003-06-17</hiredate></Emp> 
<Emp empno="101"><name>Neena Kochhar</name><hiredate>2005-09-21</hiredate></Emp> 
<Emp empno="102"><name>Lex De Haan</name><hiredate>2001-01-13</hiredate></Emp> 

10.4 XML Schemaに基づくXMLTypeビューの作成

XML Schemaに基づくXMLTypeビューのXMLデータは、XML Schemaに準拠するように制約されます。スキーマに基づくXMLTypeビューを作成するには、SQL/XMLパブリッシング関数を使用するか、オブジェクト型またはビューを使用します。

次のいずれかの方法で、スキーマに基づくビューを作成します。

  • SQL/XMLパブリッシング関数を使用する方法。

  • オブジェクト型またはオブジェクト・ビューを使用する方法。この方法は、XMLデータにマップするオブジェクト型、ビューおよび表がすでにある場合に便利です。

10.4.1 SQL/XMLパブリッシング関数を使用した、XML Schemaに基づくXMLTypeビューの作成

SQL/XMLパブリッシング関数を使用して、XML Schemaに基づくXMLTypeビューを作成できます。

  1. 必要なXML構造を含むXML Schema文書を作成および登録します。XML型とSQLオブジェクト型の間のマッピングを定義する注釈をXML Schemaに付ける必要はありません。

  2. XML Schemaに準拠するXMLTypeビューを作成するには、SQL/XMLパブリッシング関数を使用します。

この2つのステップを、それぞれ例10-2および例10-3に示します。

例10-4に、XMLTypeビューに対する問合せを示します。

例10-2では、従業員を定義するXML構造を含むemp_simple.xsdというXML Schemaがあると想定します。この例では、目的の場所http://www.oracle.com/emp_simple.xsdを使用してXML Schemaを登録します。

SQL/XMLパブリッシング関数を使用してXML Schemaに基づくコンテンツを生成する場合、すべての要素に適切な名前空間情報を指定し、xsi:schemaLocation属性を使用してスキーマの場所を指定する必要があります。これらは、XMLAttributes句を使用して指定できます。例10-3に、これを示します。

注意:

XML Schema参照とともにSQL/XML関数XMLAttributesを使用してXMLTypeビューを作成する場合は、可能であればビューを作成する前に必ずXML Schemaを登録します。そのようにしない場合、XML Schemaの登録後に、生成される文書がXML Schemaに基づくようにビューを再コンパイルすることが必要になります。

例10-3では、関数XMLElementでXML要素Employeeが作成されます。関数XMLForestは、要素Employeeの子を作成します。XMLElement内のXMLAttributes句によって、生成されたXMLがビューのXML Schemaに準拠するように、必須のXML namespaceおよびスキーマのlocation属性が作成されます。最も内側にあるXMLForest関数のコールによって、Employee要素の子である、department要素の子が作成されます。

XML生成関数は、デフォルトではXML Schemaに基づかないXMLインスタンスを生成します。ただし、スキーマ位置が属性xsi:schemaLocationまたはxsi:noNamespaceSchemaLocationを使用して指定されている場合は、Oracle XML DBによってXML Schemaに基づくXMLデータが生成されます。XMLTypeビューの場合は、要素と属性の名前がXML Schema内の要素と属性の名前に一致しているかぎり、このXMLデータが有効なXML Schemaに基づく文書に暗黙的に変換されます。生成されたXMLデータで発生したエラーは、XMLインスタンス上で検証や抽出などの操作が実行されたときに、後で検出されます。

例10-4では、XMLTypeビューを問い合せて、employeesおよび departments表からXMLの結果が戻されています。問合せの結果は、わかりやすくするためフォーマット出力しています。

例10-2 XML Schema emp_simple.xsdの登録

BEGIN
  DBMS_XMLSCHEMA.registerSchema(
   SCHEMAURL => 'http://www.oracle.com/emp_simple.xsd',
   SCHEMADOC => '<schema xmlns="http://www.w3.org/2001/XMLSchema"
                         targetNamespace="http://www.oracle.com/emp_simple.xsd"
                         version="1.0"
                         xmlns:xdb="http://xmlns.oracle.com/xdb" 
                         elementFormDefault="qualified"> 
                   <element name = "Employee"> 
                     <complexType> 
                       <sequence> 
                         <element name = "EmployeeId"
                                  type = "positiveInteger" minOccurs = "0"/> 
                         <element name = "Name"
                                  type = "string" minOccurs = "0"/> 
                         <element name = "Job"
                                  type = "string" minOccurs = "0"/> 
                         <element name = "Manager"
                                  type = "positiveInteger" minOccurs = "0"/> 
                         <element name = "HireDate"
                                  type = "date" minOccurs = "0"/> 
                         <element name = "Salary"
                                  type = "positiveInteger" minOccurs = "0"/> 
                         <element name = "Commission"
                                  type = "positiveInteger" minOccurs = "0"/> 
                         <element name = "Dept"> 
                           <complexType> 
                             <sequence> 
                               <element name = "DeptNo"
                                        type = "positiveInteger" minOccurs = "0"/> 
                               <element name = "DeptName"
                                        type = "string" minOccurs = "0"/> 
                               <element name = "Location"
                                        type = "positiveInteger" minOccurs = "0"/> 
                             </sequence> 
                           </complexType> 
                         </element> 
                       </sequence> 
                     </complexType> 
                   </element> 
                 </schema>',
   LOCAL     => TRUE,
   GENTYPES  => TRUE);
END;

例10-3 SQL/XMLパブリッシング関数を使用したXMLTypeビューの作成

CREATE OR REPLACE VIEW emp_simple_xml OF XMLType
  XMLSCHEMA "http://www.oracle.com/emp_simple.xsd" ELEMENT "Employee"
   WITH OBJECT ID (XMLCast(XMLQuery('/Employee/EmployeeId/text()'
                                    PASSING OBJECT_VALUE
                                    RETURNING CONTENT)
                           AS BINARY_DOUBLE)) AS
   SELECT
     XMLElement("Employee",
                XMLAttributes(
                  'http://www.oracle.com/emp_simple.xsd' AS "xmlns" ,
                  'http://www.w3.org/2001/XMLSchema-instance' AS "xmlns:xsi",
                  'http://www.oracle.com/emp_simple.xsd
                   http://www.oracle.com/emp_simple.xsd'
                  AS "xsi:schemaLocation"),
                XMLForest(e.employee_id    AS "EmployeeId",
                          e.last_name      AS "Name",
                          e.job_id         AS "Job",
                          e.manager_id     AS "Manager",
                          e.hire_date      AS "HireDate",
                          e.salary         AS "Salary",
                          e.commission_pct AS "Commission",
                          XMLForest(
                            d.department_id   AS "DeptNo",
                            d.department_name AS "DeptName",
                            d.location_id     AS "Location") AS "Dept"))
     FROM employees e, departments d
     WHERE e.department_id = d.department_id;

例10-4 XMLTypeビューの問合せ

SELECT OBJECT_VALUE AS RESULT FROM emp_simple_xml WHERE ROWNUM < 2;

RESULT
---------------------------------------------------------------------
<Employee xmlns="http://www.oracle.com/emp_simple.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.oracle.com/emp_simple.xsd 
                              http://www.oracle.com/emp_simple.xsd">
  <EmployeeId>200</EmployeeId>
  <Name>Whalen</Name>
  <Job>AD_ASST</Job>
  <Manager>101</Manager>
  <HireDate>2003-09-17</HireDate>
  <Salary>4400</Salary>
  <Dept>
    <DeptNo>10</Deptno>
    <DeptName>Administration</DeptName>
    <Location>1700</Location>
  </Dept>
</Employee>
10.4.1.1 SQL/XMLパブリッシング関数での名前空間の使用

複数の名前空間を含む複合XML Schemaが存在する場合は、SQL/XMLパブリッシング関数で提供される部分的にエスケープされたマッピングを使用して、適切な名前空間と接頭辞を持つ要素を作成する必要があります。

例10-5の問合せでは、正しい名前空間、接頭辞およびターゲット・スキーマの場所を持つXMLインスタンスが作成されます。これをemp_simple_xmlビューの定義で問合せとして使用できます。

XML Schemaにターゲットの名前空間が存在しない場合は、xsi:noNamespaceSchemaLocation属性を使用してターゲットの名前空間を示すことができます。例10-6に、このようなXML Schemaを示します。

例10-7では、例10-6のXML Schemaに準拠するビューが作成されます。XMLAttributes句によって、noNamespaceスキーマの場所属性を含むXML要素が作成されます。

例10-8では、XML Schema dept.xsdに準拠するビューdept_xmlが作成されます。

例10-5 SQL/XMLパブリッシング関数での名前空間接頭辞の使用

SELECT XMLElement("ipo:Employee", 
          XMLAttributes('http://www.oracle.com/emp_simple.xsd' AS "xmlns:ipo", 
                        'http://www.oracle.com/emp_simple.xsd 
                         http://www.oracle.com/emp_simple.xsd' AS "xmlns:xsi"),
            XMLForest(e.employee_id                     AS "ipo:EmployeeId", 
                      e.last_name                       AS "ipo:Name",  
                      e.job_id                          AS "ipo:Job",
                      e.manager_id                      AS "ipo:Manager",
                      TO_CHAR(e.hire_date,'YYYY-MM-DD') AS "ipo:HireDate", 
                      e.salary                          AS "ipo:Salary",
                      e.commission_pct                  AS "ipo:Commission",
                 XMLForest(d.department_id   AS "ipo:DeptNo",
                           d.department_name AS "ipo:DeptName", d.location_id
       AS "ipo:Location") AS "ipo:Dept"))
       FROM employees e, departments d 
       WHERE e.department_id = d.department_id AND d.department_id = 20;
BEGIN
  -- Delete schema if it already exists (else error)
  DBMS_XMLSCHEMA.deleteSchema('emp-noname.xsd', 4); 
END;
XMLELEMENT("IPO:EMPLOYEE",XMLATTRIBUTES('HTTP://WWW.ORACLE.COM/EMP_SIMPLE.XSD'AS
--------------------------------------------------------------------------------
<ipo:Employee
xmlns:ipo="http://www.oracle.com/emp_simple.xsd"
 xmlns:xsi="http://www.oracle.com/emp_simple.xsd
 http://www.oracle.com/emp_simple.xsd">
<ipo:EmployeeId>201</ipo:EmployeeId><ipo:Name>Hartstein</ipo:Name>
<ipo:Job>MK_MAN</ipo:Job><ipo:Manager>100</ipo:Manager>
<ipo:HireDate>2004-02-17</ipo:HireDate><ipo:Salary>13000</ipo:Salary>
<ipo:Dept><ipo:DeptNo>20</ipo:DeptNo><ipo:DeptName>Marketing</ipo:DeptName>
<ipo:Location>1800</ipo:Location></ipo:Dept></ipo:Employee>
<ipo:Employee xmlns:ipo="http://www.oracle.com/emp_simple.xsd"
 xmlns:xsi="http://www.oracle.com/emp_simple.xsd 
 http://www.oracle.com/emp_simple.xsd"><ipo:EmployeeId>202</ipo:EmployeeId>
<ipo:Name>Fay</ipo:Name><ipo:Job>MK_REP</ipo:Job><ipo:Manager>201</ipo:Manager>
<ipo:HireDate>2005-08-17</ipo:HireDate><ipo:Salary>6000</ipo:Salary>
<ipo:Dept><ipo:DeptNo>20</ipo:Dept
No><ipo:DeptName>Marketing</ipo:DeptName><ipo:Location>1800</ipo:Location>
</ipo:Dept>
</ipo:Employee>

例10-6 ターゲットの名前空間が存在しないXML Schema

BEGIN
  DBMS_XMLSCHEMA.registerSchema(
    SCHEMAURL => 'emp-noname.xsd',
    SCHEMADOC => '<schema xmlns="http://www.w3.org/2001/XMLSchema"
                          xmlns:xdb="http://xmlns.oracle.com/xdb"> 
                    <element name = "Employee"> 
                      <complexType> 
                        <sequence> 
                          <element name = "EmployeeId" type = "positiveInteger"/> 
                          <element name = "Name" type = "string"/> 
                          <element name = "Job" type = "string"/> 
                          <element name = "Manager" type = "positiveInteger"/> 
                          <element name = "HireDate" type = "date"/> 
                          <element name = "Salary" type = "positiveInteger"/> 
                          <element name = "Commission" type = "positiveInteger"/> 
                          <element name = "Dept"> 
                            <complexType> 
                              <sequence> 
                                <element name = "DeptNo" type = "positiveInteger" /> 
                                <element name = "DeptName" type = "string"/> 
                                <element name = "Location" type = "positiveInteger"/> 
                              </sequence> 
                            </complexType> 
                          </element> 
                        </sequence> 
                      </complexType> 
                    </element> 
                  </schema>',
    LOCAL     => TRUE,
    GENTYPES  => TRUE);
END;

例10-7 ターゲットの名前空間が存在しないXML Schemaのビューの作成

CREATE OR REPLACE VIEW emp_xml OF XMLType
     XMLSCHEMA "emp-noname.xsd" ELEMENT "Employee"
     WITH OBJECT ID (XMLCast(XMLQuery('/Employee/EmployeeId/text()'
                                      PASSING OBJECT_VALUE
                                      RETURNING CONTENT)
                             AS BINARY_DOUBLE)) AS
     SELECT XMLElement(
       "Employee",
       XMLAttributes('http://www.w3.org/2001/XMLSchema-instance' AS "xmlns:xsi",
                     'emp-noname.xsd' AS "xsi:noNamespaceSchemaLocation"),
       XMLForest(e.employee_id    AS "EmployeeId",
                 e.last_name      AS "Name",
                 e.job_id         AS "Job",
                 e.manager_id     AS "Manager",
                 e.hire_date      AS "HireDate",
                 e.salary         AS "Salary",
                 e.commission_pct AS "Commission",
                 XMLForest(d.department_id   AS "DeptNo",
                           d.department_name AS "DeptName",
                           d.location_id     AS "Location") AS "Dept"))
       FROM employees e, departments d
       WHERE e.department_id = d.department_id;

例10-8 XML Schemaに基づくXMLTypeビューでのSQL/XML関数の使用

BEGIN
  -- Delete schema if it already exists (else error)
  DBMS_XMLSCHEMA.deleteSchema('http://www.oracle.com/dept.xsd', 4);
END;
/

BEGIN
  DBMS_XMLSCHEMA.registerSchema(
    SCHEMAURL => 'http://www.oracle.com/dept.xsd',
    SCHEMADOC => '<schema xmlns="http://www.w3.org/2001/XMLSchema"
                          targetNamespace="http://www.oracle.com/dept.xsd"
                          version="1.0" 
                          xmlns:xdb="http://xmlns.oracle.com/xdb"
                          elementFormDefault="qualified"> 
                    <element name = "Department"> 
                      <complexType> 
                        <sequence> 
                          <element name = "DeptNo" type = "positiveInteger"/> 
                          <element name = "DeptName" type = "string"/> 
                          <element name = "Location" type = "positiveInteger"/> 
                          <element name = "Employee" maxOccurs = "unbounded"> 
                            <complexType> 
                              <sequence> 
                                <element name = "EmployeeId" type = "positiveInteger"/> 
                                <element name = "Name" type = "string"/> 
                                <element name = "Job" type = "string"/> 
                                <element name = "Manager" type = "positiveInteger"/> 
                                <element name = "HireDate" type = "date"/> 
                                <element name = "Salary" type = "positiveInteger"/> 
                                <element name = "Commission" type = "positiveInteger"/> 
                             </sequence> 
                            </complexType> 
                          </element> 
                        </sequence> 
                      </complexType> 
                    </element> 
                  </schema>',
    LOCAL     => TRUE,
    GENTYPES  => FALSE);
  END;
/

CREATE OR REPLACE VIEW dept_xml OF XMLType
  XMLSCHEMA "http://www.oracle.com/dept.xsd" ELEMENT "Department"
  WITH OBJECT ID (XMLCast(XMLQuery('/Department/DeptNo'
                                   PASSING OBJECT_VALUE RETURNING CONTENT)
                          AS BINARY_DOUBLE)) AS
  SELECT XMLElement(
    "Department",
    XMLAttributes(
      'http://www.oracle.com/emp.xsd' AS "xmlns" ,
      'http://www.w3.org/2001/XMLSchema-instance' AS "xmlns:xsi",
      'http://www.oracle.com/dept.xsd
       http://www.oracle.com/dept.xsd' AS "xsi:schemaLocation"),
    XMLForest(d.department_id AS "DeptNo",
              d.department_name AS "DeptName",
              d.location_id AS "Location"),
    (SELECT XMLagg(
              XMLElement("Employee",
                         XMLForest(
                           e.employee_id AS "EmployeeId",
                           e.last_name AS "Name",
                           e.job_id AS "Job",
                           e.manager_id AS "Manager",
                           to_char(e.hire_date,'YYYY-MM-DD') AS "Hiredate",
                           e.salary AS "Salary",
                           e.commission_pct AS "Commission")))
       FROM employees e
       WHERE e.department_id = d.department_id))
     FROM departments d;

これは、結果のXMLTypeインスタンスです。

SELECT OBJECT_VALUE AS result FROM dept_xml WHERE ROWNUM < 2;

RESULT
----------------------------------------------------------------
<Department
    xmlns="http://www.oracle.com/emp.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.oracle.com/dept.xsd 
                        http://www.oracle.com/dept.xsd">
  <DeptNo>10</DeptNo>
  <DeptName>Administration</DeptName>
  <Location>1700</Location>
  <Employee>
    <EmployeeId>200</EmployeeId>
    <Name>Whalen</Name>
    <Job>AD_ASST</Job>
    <Manager>101</Manager>
    <Hiredate>2003-09-17</Hiredate>
    <Salary>4400</Salary>
  </Employee>
</Department> 

10.4.2 オブジェクト型またはオブジェクト・ビューを使用した、XML Schemaに基づくXMLTypeビューの作成

XML型とSQLオブジェクト型およびオブジェクト属性との間のマッピングを定義する注釈をXML Schemaに付けて、オブジェクト型またはビューからXML Schemaに基づくXMLTypeビューを作成できます。

XML Schemaに基づくXMLTypeビューをオブジェクト型またはオブジェクト・ビューから作成するには、次の手順を実行します。

  1. オブジェクト型が存在しない場合は、作成します。

  2. XML Schemaを作成してから登録し、XML型とSQLオブジェクト型および属性間のマッピングを定義する注釈を付けます。

    XML Schemaを登録する前に注釈を付けます。通常は、既存のデータをラップしてXMLTypeビューを作成する前に行います。

    このようなXML Schema文書が登録されると、次の検証が実行される場合があります。

    • simpleTypeに基づく属性または要素に対するSQLType。SQL型は、対応するXMLTypeデータのXML型と互換性がある必要があります。たとえば、XML stringのデータ型は、VARCHAR2またはラージ・オブジェクト(LOB)データ型にのみマップできます。

    • complexTypeに基づく要素に対して指定されたSQLType。これは、LOBまたはcomplexTypeの宣言と互換性がある構造を持つオブジェクト型のいずれかです。オブジェクト型には、正しいデータ型を持つ正しい数の属性が含まれます。

  3. XMLTypeビューを作成し、XML SchemaのURLおよびルート要素名を指定します。ビューを定義する問合せによって、まずオブジェクト・インスタンスが作成され、これらのインスタンスがXMLに変換されます。

    1. オブジェクト・ビューを作成します。

    2. そのオブジェクト・ビューのXMLTypeビューを作成します。

この項の各トピックでは、オブジェクト型またはオブジェクト・ビューを使用して、XML Schemaに基づくXMLTypeビューを作成する例について説明します。これらは、従業員データおよび部門データを含むリレーショナル表に基づきます。

2つのXMLTypeビューをそれぞれ作成するために、同じリレーショナル・データが使用されます。従業員ビューemp_xmlでは、XML文書で従業員を記述し、ネストした情報として従業員の部門が含まれます。部門ビューdept_xmlでは、XMLデータで部門を記述し、ネストした情報として部門の従業員が含まれます。

10.4.2.1 ネストした部門情報を使用したXMLType従業員ビューの作成

この例では、オブジェクト・ビューに基づいて、XMLTypeビューemp_xmlを作成します。

ビューの作成の最後のステップでは、2つの方法があります。

10.4.2.1.1 ステップ1:XMLType従業員ビューに対応するオブジェクト型の作成

XML Schemaに基づくビューに対応するオブジェクト型を作成します。

例10-9は、その他のステップで使用されるオブジェクト型を作成しています。

例10-9 XML Schemaに基づくXMLTypeビューに対応するオブジェクト型の作成

CREATE TYPE dept_t AS OBJECT 
      (deptno NUMBER(4), 
       dname  VARCHAR2(30), 
       loc    NUMBER(4)); 
/ 

CREATE TYPE emp_t AS OBJECT 
      (empno     NUMBER(6), 
       ename     VARCHAR2(25), 
       job       VARCHAR2(10), 
       mgr       NUMBER(6), 
       hiredate  DATE, 
       sal       NUMBER(8,2), 
       comm      NUMBER(2,2), 
       dept      dept_t); 
/
10.4.2.1.2 ステップ2:XML Schema emp_complex.xsdの作成および登録

XML Schema emp_complex.xsdを作成および登録します。スキーマにより、XMLの要素と属性が、対応するオブジェクト・リレーショナル・オブジェクト属性にマップされます。

XML Schemaのemp_complex.xsdを作成し、オブジェクト型の対応するオブジェクト属性に、XML要素および属性がどのようにマップされるかを指定してから(xdb:SQLType注釈)、登録します。例10-10に登録する方法を示します。

例10-10では、目的の場所http://www.oracle.com/emp_complex.xsdを使用してXML Schemaを作成して登録します。

例10-10 XML Schema emp_complex.xsdの作成および登録

BEGIN
  -- Delete schema if it already exists (else error)
  DBMS_XMLSCHEMA.deleteSchema('http://www.oracle.com/emp_complex.xsd', 4);
END;
/

COMMIT;
 
BEGIN
  DBMS_XMLSCHEMA.registerSchema(
    SCHEMAURL => 'http://www.oracle.com/emp_complex.xsd', 
    SCHEMADOC => '<?xml version="1.0"?>
                  <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                              xmlns:xdb="http://xmlns.oracle.com/xdb" 
                              xsi:schemaLocation="http://xmlns.oracle.com/xdb 
                                                  http://xmlns.oracle.com/xdb/XDBSchema.xsd">
                    <xsd:element name="Employee" type="EMP_TType" xdb:SQLType="EMP_T"/>
                    <xsd:complexType name="EMP_TType" xdb:SQLType="EMP_T" xdb:maintainDOM="false">
                      <xsd:sequence>
                        <xsd:element name="EMPNO" type="xsd:double" xdb:SQLName="EMPNO" 
                                     xdb:SQLType="NUMBER"/>
                        <xsd:element name="ENAME" xdb:SQLName="ENAME" xdb:SQLType="VARCHAR2">
                          <xsd:simpleType>
                            <xsd:restriction base="xsd:string">
                              <xsd:maxLength value="25"/>
                            </xsd:restriction>
                          </xsd:simpleType>
                        </xsd:element>
                        <xsd:element name="JOB" xdb:SQLName="JOB" xdb:SQLType="VARCHAR2">
                          <xsd:simpleType>
                            <xsd:restriction base="xsd:string">
                              <xsd:maxLength value="10"/>
                            </xsd:restriction>
                          </xsd:simpleType>
                        </xsd:element>
                        <xsd:element name="MGR" type="xsd:double" xdb:SQLName="MGR" 
                                     xdb:SQLType="NUMBER"/>
                        <xsd:element name="HIREDATE" type="xsd:date" xdb:SQLName="HIREDATE" 
                                     xdb:SQLType="DATE"/>
                        <xsd:element name="SAL" type="xsd:double" xdb:SQLName="SAL" 
                                     xdb:SQLType="NUMBER"/>
                        <xsd:element name="COMM" type="xsd:double" xdb:SQLName="COMM" 
                                     xdb:SQLType="NUMBER"/>
                        <xsd:element name="DEPT" type="DEPT_TType" xdb:SQLName="DEPT"
                                     xdb:SQLType="DEPT_T"/>
                      </xsd:sequence>
                    </xsd:complexType>
                    <xsd:complexType name="DEPT_TType" xdb:SQLType="DEPT_T" 
                                     xdb:maintainDOM="false">
                      <xsd:sequence>
                        <xsd:element name="DEPTNO" type="xsd:double" xdb:SQLName="DEPTNO" 
                                     xdb:SQLType="NUMBER"/>
                        <xsd:element name="DNAME" xdb:SQLName="DNAME" xdb:SQLType="VARCHAR2">
                          <xsd:simpleType>
                            <xsd:restriction base="xsd:string">
                              <xsd:maxLength value="30"/>
                            </xsd:restriction>
                          </xsd:simpleType>
                        </xsd:element>
                       <xsd:element name="LOC" type="xsd:double" xdb:SQLName="LOC" 
                                    xdb:SQLType="NUMBER"/>
                      </xsd:sequence>
                    </xsd:complexType>
                  </xsd:schema>', 
    LOCAL     => TRUE, 
    GENTYPES  => FALSE);
END;
/
10.4.2.1.3 ステップ3a:オブジェクト型emp_tを使用したXMLTypeビューemp_xmlの作成

オブジェクト型を使用してXMLTypeビューを作成します。

例10-11では、オブジェクト型emp_tを使用してXMLTypeビューを作成します。

例10-11では、OBJECT ID句でSQL/XML関数XMLCastを使用して、XML従業員番号をSQLデータ型BINARY_DOUBLEに変換します。

関連項目:

ビューemp_xmlを作成する他の方法(オブジェクト・ビューemp_vを使用)は、「ステップ3b: オブジェクト・ビューemp_vを使用したXMLTypeビューemp_xmlの作成」を参照してください。

例10-11 オブジェクト型emp_tを使用したXMLTypeビューemp_xmlの作成

CREATE OR REPLACE VIEW emp_xml OF XMLType 
  XMLSCHEMA "http://www.oracle.com/emp_complex.xsd"
  ELEMENT "Employee" 
    WITH OBJECT ID (XMLCast(XMLQuery('/Employee/EMPNO'
                                     PASSING OBJECT_VALUE RETURNING CONTENT)
                            AS BINARY_DOUBLE)) AS 
  SELECT emp_t(e.employee_id, e.last_name, e.job_id, e.manager_id, e.hire_date, 
               e.salary, e.commission_pct,
               dept_t(d.department_id, d.department_name, d.location_id)) 
    FROM employees e, departments d 
    WHERE e.department_id = d.department_id;
10.4.2.1.4 ステップ3b:オブジェクト・ビューemp_vを使用したXMLTypeビューemp_xmlの作成

オブジェクト・ビューを使用してXMLTypeビューを作成します。

例10-12では、オブジェクト・ビューemp_vを作成して、そのオブジェクト・ビューに基づいてXMLTypeビューemp_xmlを作成します。

関連項目:

ビューemp_xmlを作成する他の方法(オブジェクト型emp_tを使用)は、「ステップ3a: オブジェクト型emp_tを使用したXMLTypeビューemp_xmlの作成」を参照してください。

例10-12 オブジェクト・ビューの作成と、そのオブジェクト・ビューに基づくXMLTypeビューの作成

CREATE OR REPLACE VIEW emp_v OF emp_t WITH OBJECT ID (empno) AS 
  SELECT emp_t(e.employee_id, e.last_name, e.job_id, e.manager_id, e.hire_date,
               e.salary, e.commission_pct,
               dept_t(d.department_id, d.department_name, d.location_id)) 
    FROM employees e, departments d 
    WHERE e.department_id = d.department_id;
 
CREATE OR REPLACE VIEW emp_xml OF XMLType 
  XMLSCHEMA "http://www.oracle.com/emp_complex.xsd" ELEMENT "Employee"
  WITH OBJECT ID DEFAULT AS
  SELECT VALUE(p) FROM emp_v p;
10.4.2.2 ネストした従業員情報を使用したXMLType部門ビューの作成

ネストされた従業員情報がビューの各部門に含まれるように、XMLTypeビューdept_xmlが作成されます。

ビューの作成の最後のステップでは、2つの方法があります。

10.4.2.2.1 ステップ1:XMLType部門ビューに対応するオブジェクト型の作成

XML Schemaに基づくビューに対応するオブジェクト型を作成します。

例10-13は、その他のステップで使用されるオブジェクト型を作成しています。

例10-13 オブジェクト型の作成

CREATE TYPE emp_t AS OBJECT (empno    NUMBER(6),
                             ename    VARCHAR2(25), 
                             job      VARCHAR2(10), 
                             mgr      NUMBER(6), 
                             hiredate DATE, 
                             sal      NUMBER(8,2), 
                             comm     NUMBER(2,2)); /

CREATE OR REPLACE TYPE emplist_t AS TABLE OF emp_t; 
/

CREATE TYPE dept_t AS OBJECT (deptno NUMBER(4),
                              dname  VARCHAR2(30), 
                              loc    NUMBER(4),
                              emps   emplist_t); 
/
10.4.2.2.2 ステップ2:XML Schema dept_complex.xsdの登録

XML Schema dept_complex.xsdを登録します。

例10-14に、これを示します。

例10-14 XML Schema dept_complex.xsdの登録

BEGIN
  -- Delete schema if it already exists (else error)
  DBMS_XMLSCHEMA.deleteSchema('http://www.oracle.com/dept_complex.xsd', 4);
END;
/

BEGIN
  DBMS_XMLSCHEMA.registerSchema(
    SCHEMAURL => 'http://www.oracle.com/dept_complex.xsd',
    SCHEMADOC => '<?xml version="1.0"?>
                  <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                              xmlns:xdb="http://xmlns.oracle.com/xdb"            
                              xsi:schemaLocation="http://xmlns.oracle.com/xdb 
                                                  http://xmlns.oracle.com/xdb/XDBSchema.xsd">
                    <xsd:element name="Department" type="DEPT_TType" xdb:SQLType="DEPT_T"/>
                    <xsd:complexType name="DEPT_TType" xdb:SQLType="DEPT_T" 
                                     xdb:maintainDOM="false">
                      <xsd:sequence>
                        <xsd:element name="DEPTNO" type="xsd:double" xdb:SQLName="DEPTNO" 
                                     xdb:SQLType="NUMBER"/>
                        <xsd:element name="DNAME" xdb:SQLName="DNAME" xdb:SQLType="VARCHAR2">
                          <xsd:simpleType>
                            <xsd:restriction base="xsd:string">
                              <xsd:maxLength value="30"/>
                            </xsd:restriction>
                          </xsd:simpleType>
                        </xsd:element>
                        <xsd:element name="LOC" type="xsd:double" xdb:SQLName="LOC" 
                                     xdb:SQLType="NUMBER"/>
                        <xsd:element name="EMPS" type="EMP_TType" maxOccurs="unbounded" 
                                     minOccurs="0" xdb:SQLName="EMPS" 
                                     xdb:SQLCollType="EMPLIST_T" xdb:SQLType="EMP_T"  
                                     xdb:SQLCollSchema="HR"/>
                      </xsd:sequence>
                    </xsd:complexType>
                    <xsd:complexType name="EMP_TType" xdb:SQLType="EMP_T" xdb:maintainDOM="false">
                      <xsd:sequence>
                        <xsd:element name="EMPNO" type="xsd:double" xdb:SQLName="EMPNO" 
                                     xdb:SQLType="NUMBER"/>
                        <xsd:element name="ENAME" xdb:SQLName="ENAME" xdb:SQLType="VARCHAR2">
                          <xsd:simpleType>
                            <xsd:restriction base="xsd:string">
                              <xsd:maxLength value="25"/>
                            </xsd:restriction>
                          </xsd:simpleType>
                        </xsd:element>
                        <xsd:element name="JOB" xdb:SQLName="JOB" xdb:SQLType="VARCHAR2">
                          <xsd:simpleType>
                            <xsd:restriction base="xsd:string">
                              <xsd:maxLength value="10"/>
                            </xsd:restriction>
                          </xsd:simpleType>
                        </xsd:element>
                        <xsd:element name="MGR" type="xsd:double" xdb:SQLName="MGR" 
                                     xdb:SQLType="NUMBER"/>
                        <xsd:element name="HIREDATE" type="xsd:date" xdb:SQLName="HIREDATE" 
                                     xdb:SQLType="DATE"/>
                        <xsd:element name="SAL" type="xsd:double" xdb:SQLName="SAL" 
                                     xdb:SQLType="NUMBER"/>
                        <xsd:element name="COMM" type="xsd:double" xdb:SQLName="COMM"   
                                     xdb:SQLType="NUMBER"/>
                      </xsd:sequence>
                    </xsd:complexType>
                  </xsd:schema>', 
    LOCAL     => TRUE, 
    GENTYPES  => FALSE);
END;
/
10.4.2.2.3 ステップ3a:オブジェクト型dept_tを使用したXMLTypeビューdept_xmlの作成

オブジェクト型dept_tを使用してXMLTypeビューdept_xmlを作成します。

例10-15に、これを示します。

例10-15 オブジェクト型dept_tを使用したXMLTypeビューdept_xmlの作成

CREATE OR REPLACE VIEW dept_xml OF XMLType
  XMLSCHEMA "http://www.oracle.com/dept_complex.xsd" ELEMENT "Department"
  WITH OBJECT ID (XMLCast(XMLQuery('/Department/DEPTNO'
                                   PASSING OBJECT_VALUE RETURNING CONTENT)
                          AS BINARY_DOUBLE)) AS
  SELECT dept_t(d.department_id, d.department_name, d.location_id,
                cast(MULTISET
                     (SELECT emp_t(e.employee_id, e.last_name, e.job_id,
                                   e.manager_id, e.hire_date,
                                   e.salary, e.commission_pct) 
                        FROM employees e WHERE e.department_id = d.department_id) 
                     AS emplist_t))
    FROM departments d;
10.4.2.2.4 ステップ3b:リレーショナル・データを直接使用したXMLTypeビューdept_xmlの作成

オブジェクト型dept_tを使用せずに、SQL/XMLパブリッシング関数を使用してリレーショナル表からXMLTypeビューdept_xmlを作成できます。

例10-16に、これを示します。

注意:

XML Schemaおよび要素情報は、ビュー・レベルで指定する必要があります。これは、SELECTリストでは、基礎となる表から別のXML SchemaのXMLが任意で作成される可能性があるためです。

例10-16 リレーショナル・データを直接使用したXMLTypeビューdept_xmlの作成

CREATE OR REPLACE VIEW dept_xml OF XMLType
  XMLSCHEMA "http://www.oracle.com/dept_complex.xsd" ELEMENT "Department"
  WITH OBJECT ID (XMLCast(XMLQuery('/Department/DEPTNO'
                                   PASSING OBJECT_VALUE RETURNING CONTENT)
                          AS BINARY_DOUBLE)) AS
  SELECT  
    XMLElement(
      "Department",
      XMLAttributes('http://www.oracle.com/dept_complex.xsd' AS "xmlns",        
                    'http://www.w3.org/2001/XMLSchema-instance' AS "xmlns:xsi",
                    'http://www.oracle.com/dept_complex.xsd 
                     http://www.oracle.com/dept_complex.xsd' 
                      AS "xsi:schemaLocation"),
      XMLForest(d.department_id "DeptNo", d.department_name "DeptName",
                d.location_id "Location"),
      (SELECT XMLAgg(XMLElement("Employee",
                                XMLForest(e.employee_id "EmployeeId", 
                                          e.last_name "Name", 
                                          e.job_id "Job", 
                                          e.manager_id "Manager", 
                                          e.hire_date "Hiredate",
                                          e.salary "Salary",
                                          e.commission_pct "Commission")))
                      FROM employees e WHERE e.department_id = d.department_id))
    FROM departments d;

10.5 XMLType表からのXMLTypeビューの作成

たとえば、XMLデータを変換したり、戻される行を制限することによって、XMLType表のXMLTypeビューを作成できます。

例10-17では、基礎となるXMLType表に含まれる行を制限して、XMLTypeビューを作成します。XML Schema dept_complex.xsdを使用して、基礎となる表を作成しています。ネストした従業員情報を使用したXMLType部門ビューの作成を参照してください。

例10-18は、XSLスタイルシートを使用してXMLデータを変換することによって、XMLTypeビューを作成する方法を示しています。

例10-17 XMLType表の行の制限によるXMLTypeビューの作成

CREATE TABLE dept_xml_tab OF XMLType 
    XMLSchema "http://www.oracle.com/dept_complex.xsd" ELEMENT "Department"
    NESTED TABLE XMLDATA."EMPS" STORE AS dept_xml_tab_tab1;
 
CREATE OR REPLACE VIEW dallas_dept_view OF XMLType 
    XMLSchema "http://www.oracle.com/dept.xsd" ELEMENT "Department"
        AS SELECT OBJECT_VALUE FROM dept_xml_tab 
           WHERE XMLCast(XMLQuery('/Department/LOC'
                                  PASSING OBJECT_VALUE RETURNING CONTENT)
                         AS VARCHAR2(20))
                 = 'DALLAS'; 

dallas_dept_viewによって、XMLType表の行が、所在地がダラスである部門に制限されます。

例10-18 XMLType表の変換によるXMLTypeビューの作成

CREATE OR REPLACE VIEW hr_po_tab OF XMLType 
  ELEMENT "PurchaseOrder" WITH OBJECT ID DEFAULT AS
  SELECT XMLtransform(OBJECT_VALUE, x.col1)
    FROM purchaseorder p, xsl_tab x;

10.6 SQL関数REFを使用したXMLTypeビュー・オブジェクトの参照

XMLTypeビュー・オブジェクトは、SQL関数refを使用して参照できます。

SELECT ref(d) FROM dept_xml_tab d;

XMLTypeビュー参照は、次のいずれかのオブジェクトIDに基づきます。

  • システム生成OID: XMLType表のビューまたはオブジェクト・ビュー

  • 主キー・ベースのOID: OBJECT ID式を持つビュー

これらのREFは、OCIオブジェクト・キャッシュ内のOCIXMLTypeインスタンスをフェッチするために使用できます。また、SQL問合せ内でも使用できます。これらのREFは、オブジェクト・ビューへのREFと同様に動作します。

10.7 XMLTypeビューでのデータ操作言語(DML)の使用

特定のXMLTypeビューは、暗黙的に更新可能でないことがあります。その場合は、すべてのDMLを処理するために、INSTEAD OFトリガーを作成する必要があります。XMLTypeビューが暗黙的に更新可能であるかどうかを識別するには、それに対して問合せを実行して、そのビューが、本来更新可能であるオブジェクト・ビューまたはオブジェクト・コンストラクタに基づいているかどうかを確認します。

例10-19に、これを示します。

例10-19 暗黙的に更新可能なXMLTypeビューの識別およびその更新

CREATE TYPE dept_t AS OBJECT 
      (deptno NUMBER(4), 
       dname  VARCHAR2(30), 
       loc    NUMBER(4)); 
/

BEGIN
  -- Delete schema if it already exists (else error)
  DBMS_XMLSCHEMA.deleteSchema('http://www.oracle.com/dept_t.xsd', 4);
END;
/
COMMIT;
 
BEGIN
  DBMS_XMLSCHEMA.registerSchema(
    SCHEMAURL => 'http://www.oracle.com/dept_t.xsd',
    SCHEMADOC => '<?xml version="1.0"?>
                  <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                              xmlns:xdb="http://xmlns.oracle.com/xdb" 
                              xsi:schemaLocation="http://xmlns.oracle.com/xdb 
                                                  http://xmlns.oracle.com/xdb/XDBSchema.xsd">
                    <xsd:element name="Department" type="DEPT_TType" xdb:SQLType="DEPT_T"/>
                    <xsd:complexType name="DEPT_TType" xdb:SQLType="DEPT_T"
                                     xdb:maintainDOM="false">
                      <xsd:sequence>
                        <xsd:element name="DEPTNO" type="xsd:double" xdb:SQLName="DEPTNO" 
                                     xdb:SQLType="NUMBER"/>
                        <xsd:element name="DNAME" xdb:SQLName="DNAME" xdb:SQLType="VARCHAR2">
                          <xsd:simpleType>
                            <xsd:restriction base="xsd:string">
                              <xsd:maxLength value="30"/>
                            </xsd:restriction>
                          </xsd:simpleType>
                        </xsd:element>
                        <xsd:element name="LOC" type="xsd:double" xdb:SQLName="LOC" 
                                     xdb:SQLType="NUMBER"/>
                      </xsd:sequence>
                    </xsd:complexType>
                  </xsd:schema>', 
    LOCAL     => TRUE, 
    GENTYPES  => FALSE);
END;
/

CREATE OR REPLACE VIEW dept_xml of XMLType
  XMLSchema "http://www.oracle.com/dept_t.xsd" element "Department"
  WITH OBJECT ID (XMLCast(XMLQuery('/Department/DEPTNO'
                                   PASSING OBJECT_VALUE RETURNING CONTENT)
                          AS BINARY_DOUBLE)) AS
  SELECT dept_t(d.department_id, d.department_name, d.location_id) 
    FROM departments d;

INSERT INTO dept_xml 
  VALUES (
    XMLType.createXML(
      '<Department 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:noNamespaceSchemaLocation="http://www.oracle.com/dept_t.xsd" >
         <DEPTNO>300</DEPTNO>
         <DNAME>Processing</DNAME>
         <LOC>1700</LOC>
       </Department>'));

UPDATE dept_xml d
  SET d.OBJECT_VALUE =
    XMLQuery('copy $i := $p1 modify
                (for $j in $i/Department/DNAME
                 return replace value of node $j with $p2)
              return $i'
             PASSING d.OBJECT_VALUE AS "p1", 'Shipping' AS "p2" RETURNING CONTENT)
    WHERE XMLExists('/Department[DEPTNO=300]' PASSING OBJECT_VALUE);