この章では、XMLTypeビューを作成および使用する方法を説明します。内容は次のとおりです。
XMLTypeビューは、既存のリレーショナル・データおよびオブジェクト・リレーショナル・データをXML形式でラップします。XMLTypeビューを使用する主なメリットは次のとおりです。
基本のレガシー・データを移行せずに、XML Schema機能を使用するOracle XML DBのXML機能を使用できます。
XMLTypeビューでは、XMLType表で使用可能なオブジェクト・リレーショナル記憶域、CLOB記憶域、バイナリXML記憶域の他に、様々な形式の記憶域を使用できます。
XMLTypeビューは、オブジェクト・ビューに類似しています。XMLTypeビューの各行は、XMLTypeインスタンスに対応しています。ビュー内の各行を一意に識別するためのオブジェクト識別子は、SQL/XML関数XMLCastおよびXMLQuery()を使用して作成できます。
この章では、XML Schemaとは、W3CのXML Schema 1.0勧告(http://www.w3.org/XML/Schema)のことを指します。
XMLTypeビューには2つのタイプがあります。
XML Schemaに基づくXMLTypeビュー。XMLType表に関して、特定のXML Schemaに準拠するXMLTypeビューは、XML Schemaに基づくXMLTypeビューと呼びます。これらのビューでは、XML Schemaに基づかないXMLTypeビューより厳密な型指定ができます。
XMLTypeビューに対する問合せのXPathリライトは、XML Schemaに基づくXMLTypeビューとXML Schemaに基づかないXMLTypeビューの両方で可能です。XPathリライトの詳細は、第8章「構造化記憶域のXPathリライト」で説明しています。
XML Schemaに基づくXMLTypeビューを作成するには、最初にXML Schemaを登録します。ビューがオブジェクト・ビューである場合、つまりオブジェクト型を使用して構成されている場合、XML Schemaには、XMLとSQLオブジェクト型の間の双方向マッピングを表す注釈が必要です。その後、適切なSQLオブジェクト型のインスタンスを構築する基礎となる問合せを指定することによって、登録されたXML Schemaに準拠するXMLTypeビューを作成できます。
XMLTypeビューは、次のいずれかの方法で作成できます。
XMLElement、XMLForest、XMLConcat、XMLAggなどのSQL/XMLパブリッシング関数に基づいて構成する方法。SQL/XMLパブリッシング関数を使用すると、XML Schemaに基づかないXMLTypeビューとXML Schemaに基づくXMLTypeビューの両方を構成できます。これによって、リレーショナル・レガシー・データをXMLに物理的に移行せずに、基礎となるリレーショナル表から直接XMLTypeビューを構成できます。ただし、XML Schemaに基づくXMLTypeビューを構成するには、XML Schemaを登録する必要があり、SQL/XMLパブリッシング関数によって生成されたXML値はXML Schemaに制限される必要があります。
オブジェクト型、オブジェクト・ビューおよびOracle SQL関数sys_XMLGenに基づいて構成する方法。XML Schemaに基づかないXMLTypeビューは、オブジェクト型、オブジェクト・ビューおよび関数sys_XMLGenを使用して構成できます。XML Schemaに基づくXMLTypeビューは、オブジェクト型およびオブジェクト・ビューを使用して構成できます。これによって、リレーショナルまたはオブジェクト・リレーショナルのレガシー・データをXMLに物理的に移行せずに、基礎となるリレーショナル表またはオブジェクト・リレーショナル表から直接XMLTypeビューを構成できます。XML Schemaに基づかないXMLTypeビューの作成では、既存のオブジェクト型またはオブジェクト・ビューに対してsys_XMLGenを使用する必要があります。XML Schemaに基づくXMLTypeビューでは、既存のオブジェクト型へのマッピングをXML Schemaに注釈として付けるか、または既存のオブジェクト型からXML Schemaを生成する必要があります。
XMLType表から直接構成する方法。
図19-1に、XMLTypeビューを作成するためのCREATE VIEW句を示します。CREATE VIEWの構文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
XML Schemaに基づかないXMLTypeビューは、結果として戻されるXML値が、登録されたXML Schema内の特定の要素に制限されないXMLTypeビューです。XML Schemaに基づかないXMLTypeビューは、次のいずれかの方法で作成できます。
SQL/XMLパブリッシング関数を使用する方法。
Oracle SQL関数sys_XMLGenと、オブジェクト型またはオブジェクト・ビューを使用する方法。この方法は、XMLデータにマップするオブジェクト型、ビューおよび表がすでにある場合に便利です。
例19-1に、SQL/XML関数XMLELementを使用してXMLTypeビューを作成する方法を示します。
例19-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>
リレーショナル表またはリレーショナル・ビュー内の既存のデータは、この方法を使用してXMLとして公開できます。ビューがSQL/XMLパブリッシング関数によって生成されると、XPath式を使用してそのビューにアクセスする問合せは、多くの場合リライトされます。最適化された問合せは、基礎となるリレーショナル列に直接アクセスできます。詳細は、第8章「構造化記憶域のXPathリライト」を参照してください。
これらのXMLTypeビューに対してDML操作を行うことができますが、通常、DML操作を処理するためにINSTEAD OFトリガーを作成する必要があります。
オブジェクト型とOracle SQL関数sys_XMLGenを使用して、XMLTypeビューを作成することもできます。関数sys_XMLGenは、引数としてオブジェクト型のインスタンスを受け入れ、対応するXMLTypeのインスタンスを生成します。例19-2の問合せでは、sys_XMLGenを使用し、例19-1の問合せと同じ結果を生成します。
例19-2 オブジェクト型およびSYS_XMLGENを使用したXMLTypeビューの作成
CREATE TYPE emp_t AS OBJECT ("@empno" NUMBER(6),
fname VARCHAR2(20),
lname VARCHAR2(25),
hiredate DATE);
/
CREATE OR REPLACE VIEW employee_view OF XMLType
WITH OBJECT ID (XMLCast(XMLQuery('/Emp/@empno'
PASSING OBJECT_VALUE RETURNING CONTENT)
AS BINARY_DOUBLE)) AS
SELECT sys_XMLGen(emp_t(e.employee_id, e.first_name, e.last_name, e.hire_date),
XMLFormat('EMP'))
FROM employees e WHERE salary > 15000;
SELECT * FROM employee_view;
SYS_NC_ROWINFO$
--------------------------------------------------------
<?xml version="1.0"?
<EMP empno="100">
<FNAME>Steven</FNAME>
<LNAME>King</LNAME>
<HIREDATE>17-JUN-03</HIREDATE>
</EMP>
<?xml version="1.0"?>
<EMP empno="101">
<FNAME>Neena</FNAME>
<LNAME>Kochhar</LNAME>
<HIREDATE>21-SEP-05</HIREDATE>
</EMP>
<?xml version="1.0"?>
<EMP empno="102">
<FNAME>Lex</FNAME>
<LNAME>De Haan</LNAME>
<HIREDATE>13-JAN-01</HIREDATE>
</EMP>
既存のリレーショナル・データまたはオブジェクト・リレーショナル・データは、このメカニズムを使用してXMLデータとして公開できます。
XML Schemaに基づくXMLTypeビューは、データがXML Schemaに準拠するように制約されるビューです。XML Schemaに基づくXMLTypeビューは、次のいずれかの方法で作成できます。
SQL/XMLパブリッシング関数を使用する方法。
オブジェクト型またはオブジェクト・ビューを使用する方法。この方法は、XMLデータにマップするオブジェクト型、ビューおよび表がすでにある場合に便利です。
SQL/XMLパブリッシング関数を使用すると、「XML Schemaに基づかないXMLTypeビューの作成」の項で説明したXML Schemaに基づかない場合と同様の方法で、XML Schemaに基づくXMLTypeビューを作成できます。
必要なXML構造を含むXML Schema文書を作成および登録します。XML型とSQLオブジェクト型の間のマッピングを定義する注釈をXML Schemaに付ける必要はありません。
XML Schemaに準拠するXMLTypeビューを作成するには、SQL/XMLパブリッシング関数を使用します。
この2つの手順を、それぞれ例19-3および例19-4に示します。
例19-3 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;
例19-3では、従業員を定義するXML構造を含むemp_simple.xsdというXML Schemaがあると想定します。この例では、目的の場所http://www.oracle.com/emp_simple.xsdを使用してXML Schemaを登録します。
SQL/XMLパブリッシング関数を使用してXML Schemaに基づくコンテンツを生成する場合、すべての要素に適切な名前空間情報を指定し、xsi:schemaLocation属性を使用してスキーマの場所を指定する必要があります。これらは、XMLAttributes句を使用して指定できます。例19-4に、これを示します。
例19-4 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;
例19-4では、関数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インスタンス上で検証や抽出などの操作が実行されたときに、後で検出されます。
例19-5では、XMLTypeビューを問い合せて、employeesおよび departments表からXMLの結果が戻されています。問合せの結果は、わかりやすくするためフォーマット出力しています。
例19-5 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>
複数の名前空間を含む複合XML Schemaが存在する場合は、SQL/XMLパブリッシング関数で提供される部分的にエスケープされたマッピングを使用して、適切な名前空間と接頭辞を持つ要素を作成する必要があります。
例19-6の問合せでは、正しい名前空間、接頭辞およびターゲット・スキーマの場所を持つXMLインスタンスが作成されます。これをemp_simple_xmlビューの定義で問合せとして使用できます。
例19-6 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>
XML Schemaにターゲットの名前空間が存在しない場合は、xsi:noNamespaceSchemaLocation属性を使用してターゲットの名前空間を示すことができます。例19-7に、このようなXML Schemaを示します。
例19-7 ターゲットの名前空間が存在しない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;
例19-8では、例19-7のXML Schemaに準拠するビューが作成されます。XMLAttributes句によって、noNamespaceスキーマの場所属性を含むXML要素が作成されます。
例19-8 ターゲットの名前空間が存在しない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;
例19-9では、ビューdept_xmlが作成されます。このビューは、XML Schema dept.xsdに準拠します。
例19-9 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 "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",
to_char(e.hire_date,'YYYY-MM-DD') "Hiredate",
e.salary "Salary",
e.commission_pct "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>
XML Schemaに基づくXMLTypeビューをオブジェクト型またはオブジェクト・ビューから作成するには、次の手順を実行します。
オブジェクト型が存在しない場合は、作成します。
XML Schemaを作成してから登録し、XML型とSQLオブジェクト型および属性間のマッピングを定義する注釈を付けます。
XML Schemaを登録する前に、XML Schemaに注釈を付けることができます。通常は、既存のデータをラップしてXMLTypeビューを作成する前に行います。
PL/SQL関数DBMS_XMLSchema.generateSchemaおよびDBMS_XMLSchema.generateSchemasを使用して、指定したオブジェクト型に対するデフォルトのXMLマッピングを生成できます。生成されたXML Schemaには、必要な注釈のSQLTypeやSQLSchemaなどがあります。このようなXML Schema文書が登録されると、次の検証が実行される場合があります。
simpleTypeに基づく属性または要素に対するSQLType。SQL型は、対応するXMLTypeデータのXML型と互換性がある必要があります。たとえば、XML stringのデータ型は、VARCHAR2またはラージ・オブジェクト(LOB)データ型にのみマップできます。
complexTypeに基づく要素に対して指定されたSQLType。これは、LOBまたはcomplexTypeの宣言と互換性がある構造を持つオブジェクト型のいずれかです。オブジェクト型には、正しいデータ型を持つ正しい数の属性が含まれます。
XMLTypeビューを作成し、XML SchemaのURLおよびルート要素名を指定します。ビューを定義する問合せによって、まずオブジェクト・インスタンスが作成され、これらのインスタンスがXMLに変換されます。
オブジェクト・ビューを作成します。
そのオブジェクト・ビューのXMLTypeビューを作成します。
次の各項では、オブジェクト型またはオブジェクト・ビューを使用して、XML Schemaに基づくXMLTypeビューを作成する例について説明します。これらは、従業員データおよび部門データを含むリレーショナル表に基づきます。
2つのXMLTypeビューをそれぞれ作成するために、同じリレーショナル・データが使用されます。従業員ビューemp_xmlでは、XML文書で従業員を記述し、ネストした情報として従業員の部門が含まれます。部門ビューdept_xmlでは、XMLデータで部門を記述し、ネストした情報として部門の従業員が含まれます。
この項では、オブジェクト・ビューに基づいたXMLTypeビューemp_xmlの作成方法について説明します。最後の手順には、2つの代替方法があります。
手順3a: オブジェクト型emp_tを使用したXMLTypeビューemp_xmlの作成: オブジェクト型emp_tを使用してXMLTypeビューemp_xmlを作成します。
手順3b: オブジェクト・ビューemp_vを使用したXMLTypeビューemp_xmlの作成: オブジェクト型emp_vを使用してXMLTypeビューemp_xmlを作成します。
例19-10は、その他の手順で使用されるオブジェクト型を作成しています。
XML Schemaは、手動で作成するか、またはパッケージDBMS_XMLSCHEMAを使用して既存のオブジェクト型から自動的に作成できます。例19-11を参照してください。
例19-11 DBMS_XMLSCHEMA.GENERATESCHEMAによるXML Schemaの生成
SELECT DBMS_XMLSCHEMA.generateSchema('HR','EMP_T') AS result FROM DUAL;
例19-11では、emp_t型のXML Schemaが生成されます。PL/SQL関数DBMS_XMLSCHEMA.generateSchemasには、名前空間を追加するためなどの、様々な引数を指定できます。このXML Schemaを編集して、生成されたデフォルトのマッピングを変更することもできます。関数generateSchemasは、オブジェクト型とその属性が参照するSQLデータベース・スキーマごとに、1つのXML Schemaのリストを生成します。
例19-12は、XML Schema emp_complex.xsdを登録する方法を示しています。このXML Schemaでは、オブジェクト型の対応するオブジェクト属性に、XML要素および属性がどのようにマップされるかを指定します(xdb:SQLType注釈)。
例19-12 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"
xdb:SQLSchema="HR"/>
<xsd:complexType name="EMP_TType" xdb:SQLType="EMP_T" xdb:SQLSchema="HR"
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:SQLSchema="HR" xdb:SQLType="DEPT_T"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="DEPT_TType" xdb:SQLType="DEPT_T" xdb:SQLSchema="HR"
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;
/
例19-12では、目的の場所http://www.oracle.com/emp_complex.xsdを使用してXML Schemaを登録します。
例19-13では、オブジェクト型emp_tを使用してXMLTypeビューを作成します。
例19-13 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;
例19-13では、OBJECT ID句でSQL/XML関数XMLCastを使用して、XML従業員番号をSQLデータ型BINARY_DOUBLEに変換します。
例19-14では、オブジェクト・ビューに基づいてXMLTypeビューを作成します。
例19-14 オブジェクト・ビューの作成と、そのオブジェクト・ビューへの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;
この項では、XMLTypeビューdept_xmlの作成方法について説明します。このビューの各部門には、ネストされた従業員情報が含まれます。最後の手順には、2つの代替方法があります。
手順3a: オブジェクト型dept_を使用したXMLTypeビューdept_xmlの作成: 部門用のオブジェクト型dept_tを使用してXMLTypeビューdept_xmlを作成します。
手順3b: リレーショナル・データを直接使用したXMLTypeビューdept_xmlの作成: リレーショナル・データを直接使用してXMLTypeビューdept_xmlを作成します。
例19-15は、その他の手順で使用されるオブジェクト型を作成しています。
例19-15 オブジェクト型の作成
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);
/
既存のXML Schemaを使用するか、または関数DBMS_XMLSCHEMA.generateSchemaまたはDBMS_XMLSCHEMA.generateSchemasを使用してオブジェクト型からXML Schemaを生成します(例19-11を参照)。例19-16では、XML Schema dept_complex.xsdを登録します。
例19-16 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"
xdb:SQLSchema="HR"/>
<xsd:complexType name="DEPT_TType" xdb:SQLType="DEPT_T" xdb:SQLSchema="HR"
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:SQLSchema="HR" xdb:SQLCollSchema="HR"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="EMP_TType" xdb:SQLType="EMP_T" xdb:SQLSchema="HR"
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;
/
例19-17では、オブジェクト型dept_tを使用してXMLTypeビューdept_xmlを作成します。
例19-17 オブジェクト型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;
また、オブジェクト型dept_tを使用せずに、SQL/XMLパブリッシング関数を使用してリレーショナル表からXMLTypeビューdept_xmlを作成することもできます。例19-18に、これを示します。
例19-18 リレーショナル・データを直接使用した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;
|
注意: XML Schemaおよび要素情報は、ビュー・レベルで指定する必要があります。これは、SELECTリストでは、基礎となる表から別のXML SchemaのXMLが任意で作成される可能性があるためです。 |
たとえば、XMLデータを変換したり、戻される行を制限することによって、XMLType表のXMLTypeビューを作成できます。
例19-19では、基礎となるXMLType表に含まれる行を制限して、XMLTypeビューを作成します。XML Schema dept_complex.xsdを使用して、基礎となる表を作成しています。「ネストした従業員情報を使用したXMLType部門ビューの作成」を参照してください。
例19-19 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';
CREATE OR REPLACE VIEW dallas_dept_view OF XMLType
dallas_dept_viewによって、XMLType表の行が、所在地がダラスである部門に制限されます。
例19-20は、スタイルシートを使用してXMLデータを変換することによって、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と同様に動作します。
特定のXMLTypeビューは、暗黙的に更新可能でないことがあります。その場合は、すべてのデータ操作(DML)を処理するために、INSTEAD-OF TRIGGERSを作成する必要があります。XMLTypeビューが暗黙的に更新可能である場合を識別する1つの方法は、ビュー問合せを使用して、そのビューが、本来更新可能であるオブジェクト・ビューまたはオブジェクト・コンストラクタに基づいているかどうかを判断することです。例19-21に、これを示します。
例19-21 暗黙的に更新可能な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.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"
xdb:SQLSchema="HR"/>
<xsd:complexType name="DEPT_TType" xdb:SQLType="DEPT_T" xdb:SQLSchema="HR"
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 = updateXML(d.OBJECT_VALUE, '/Department/DNAME/text()',
'Shipping')
WHERE XMLExists('/Department[DEPTNO=300]' PASSING OBJECT_VALUE);