如何将XML数据存储在Oracle中的表中?
问题陈述:
您需要将本机XML数据存储到数据库中的关系表中。
解:
Oracle有几种存储XML文档的方法。在不需要更改XML或可以使用XSLT提取XML的一部分的情况下,一种存储数据的方法是使用XMLTYPE数据转换。
我们将使用XMLTYPE调用将提供的文本转换为XMLTYPE数据类型。在后台,OracleXMLTYPE支持CLOB数据类型,因为XML在内部存储为CLOB。这意味着我们可以使用相同的方法进行转换,将调用传递给XMLTYPE一个最大4GB的字符串。
强制转换为XMLTYPE对我们的XML数据强制执行一些规则。如果使用XML架构定义了列或表,则该架构将用于验证数据,确保存在强制性元素,并且整个结构准确地映射到该架构。
我们将首先创建一个表来存储XML。
创建表tmp_store_xml(结果XMLTYPE);
码
DECLARE
result XMLTYPE;
data VARCHAR2(10);
BEGIN
FOR CUR IN (SELECT department_id FROM departments)
LOOP
WITH tmp AS
(SELECT XMLROOT(XMLFOREST( dept_t(department_id, department_name,
CAST(MULTISET
(SELECT student_id,
first_name,
last_name,
phone_number
FROM students e
WHERE e.department_id = d.department_id
) AS stulist_t
)) AS "Department"),version '1.0') AS dataxml
FROM departments d
WHERE d.department_id = '' || cur.department_id || ''
)
SELECT XMLTYPE.CREATEXML(XMLSERIALIZE(CONTENT (dataxml) INDENT size=2))
INTO result
FROM tmp;
INSERT INTO tmp_store_xml VALUES(result);
COMMIT;
END LOOP;
END;输出:表中的一行
<Department DEPTNO="60">
<DNAME>IT</DNAME>
<STU_LIST>
<STU_T STUNO="103">
<FNAME>BROWN</FNAME>
<LNAME>MICHAEL</LNAME>
<PHONE>111.111.1248</PHONE>
</STU_T>
<STU_T STUNO="104">
<FNAME>JONES</FNAME>
<LNAME>WILLIAM</LNAME>
<PHONE>111.111.1249</PHONE>
</STU_T>
<STU_T STUNO="105">
<FNAME>MILLER</FNAME>
<LNAME>DAVID</LNAME>
<PHONE>111.111.1250</PHONE>
</STU_T>
<STU_T STUNO="106">
<FNAME>DAVIS</FNAME>
<LNAME>RICHARD</LNAME>
<PHONE>111.111.1251</PHONE>
</STU_T>
<STU_T STUNO="107">
<FNAME>GARCIA</FNAME>
<LNAME>CHARLES</LNAME>
<PHONE>111.111.1252</PHONE>
</STU_T>
</STU_LIST>
</Department>数据准备:用于该问题的数据如下所示。数据完全用于演示目的。
示例
DROP TABLE students;
COMMIT;
CREATE TABLE students
( student_id NUMBER(6)
, first_name VARCHAR2(20)
, last_name VARCHAR2(25)
, email VARCHAR2(40)
, phone_number VARCHAR2(20)
, join_date DATE
, class_id VARCHAR2(20)
, fees NUMBER(8,2)
, professor_id NUMBER(6)
, department_id NUMBER(4)
) ;示例
CREATE UNIQUE INDEX stu_id_pk ON students (student_id) ;
INSERT INTO students VALUES (100,'SMITH','JAMES','SMITH.JAMES@notreal.com','111.111.1245',TO_DATE('17-06-2003','DD-MM-YYYY'),'INS_CHAIRMAN',24000,NULL,NULL);
INSERT INTO students VALUES (101,'JOHNSON','JOHN','JOHNSON.JOHN@notreal.com','111.111.1246',TO_DATE('21-09-2005','DD-MM-YYYY'),'INS_VP',17000,100,90);
INSERT INTO students VALUES (102,'WILLIAMS','ROBERT','WILLIAMS.ROBERT@notreal.com','111.111.1247',TO_DATE('13-01-2001','DD-MM-YYYY'),'INS_VP',17000,100,90);
INSERT INTO students VALUES (103,'BROWN','MICHAEL','BROWN.MICHAEL@notreal.com','111.111.1248',TO_DATE('03-01-2006','DD-MM-YYYY'),'INS_STAFF',9000,102,60);
INSERT INTO students VALUES (104,'JONES','WILLIAM','JONES.WILLIAM@notreal.com','111.111.1249',TO_DATE('21-05-2007','DD-MM-YYYY'),'INS_STAFF',6000,103,60);
INSERT INTO students VALUES (105,'MILLER','DAVID','MILLER.DAVID@notreal.com','111.111.1250',TO_DATE('25-06-2005','DD-MM-YYYY'),'INS_STAFF',4800,103,60);
INSERT INTO students VALUES (106,'DAVIS','RICHARD','DAVIS.RICHARD@notreal.com','111.111.1251',TO_DATE('05-02-2006','DD-MM-YYYY'),'INS_STAFF',4800,103,60);
INSERT INTO students VALUES (107,'GARCIA','CHARLES','GARCIA.CHARLES@notreal.com','111.111.1252',TO_DATE('07-02-2007','DD-MM-YYYY'),'INS_STAFF',4200,103,60);
INSERT INTO students VALUES (108,'RODRIGUEZ','JOSEPH','RODRIGUEZ.JOSEPH@notreal.com','111.111.1253',TO_DATE('17-08-2002','DD-MM-YYYY'),'CL_PHY',12008,101,100);
INSERT INTO students VALUES (109,'WILSON','THOMAS','WILSON.THOMAS@notreal.com','111.111.1254',TO_DATE('16-08-2002','DD-MM-YYYY'),'CL_MATH',9000,108,100);
INSERT INTO students VALUES (110,'MARTINEZ','CHRISTOPHER','MARTINEZ.CHRISTOPHER@notreal.com','111.111.1255',TO_DATE('28-09-2005','DD-MM-YYYY'),'CL_MATH',8200,108,100);
INSERT INTO students VALUES (111,'ANDERSON','DANIEL','ANDERSON.DANIEL@notreal.com','111.111.1256',TO_DATE('30-09-2005','DD-MM-YYYY'),'CL_MATH',7700,108,100);
INSERT INTO students VALUES (112,'TAYLOR','PAUL','TAYLOR.PAUL@notreal.com','111.111.1257',TO_DATE('07-03-2006','DD-MM-YYYY'),'CL_MATH',7800,108,100);
INSERT INTO students VALUES (113,'THOMAS','MARK','THOMAS.MARK@notreal.com','111.111.1258',TO_DATE('07-12-2007','DD-MM-YYYY'),'CL_MATH',6900,108,100);
COMMIT;示例
CREATE TABLE departments
( department_id NUMBER(4)
, department_name VARCHAR2(30)
CONSTRAINT dept_name_nn NOT NULL
, professor_id NUMBER(6)
, location_id NUMBER(4)
) ;示例
INSERT INTO departments VALUES ( 10, 'Administration', 200, 1700); INSERT INTO departments VALUES ( 20, 'Teaching', 201, 1800); INSERT INTO departments VALUES ( 30 , 'Purchasing' , 114 , 1700 ); INSERT INTO departments VALUES ( 40 , 'Human Resources' , 203 , 2400 ); INSERT INTO departments VALUES ( 50 , 'Students' , 121 , 1500 ); INSERT INTO departments VALUES ( 60 , 'IT' , 103 , 1400 ); INSERT INTO departments VALUES ( 70 , 'Public Relations' , 204 , 2700 ); INSERT INTO departments VALUES ( 80 , 'Fee collectors' , 145 , 2500 ); INSERT INTO departments VALUES ( 90 , 'Executive' , 100 , 1700 ); INSERT INTO departments VALUES ( 100 , 'Finance' , 108 , 1700 ); INSERT INTO departments VALUES ( 110 , 'Accounting' , 205 , 1700 ); INSERT INTO departments VALUES ( 120 , 'Treasury' , NULL , 1700 ); INSERT INTO departments VALUES ( 130 , 'Corporate Tax' , NULL , 1700 ); INSERT INTO departments VALUES ( 140 , 'Control And Credit' , NULL , 1700 ); INSERT INTO departments VALUES ( 160 , 'Benefits' , NULL , 1700 ); INSERT INTO departments VALUES ( 230 , 'Helpdesk' , NULL , 1700 ); COMMIT;