在 SQL 中查询 XML
| SQL> xquery 2 for $var1 in (1,2,3,4,5,6,7,8,9) 3 let $var2 := $var1 + 1 4 where $var2 < 6 5 order by $var2 descending 6 return $var2 7 / Result Sequence ------------------ 5 4 3 2 |
| create table acc_comm_log ( acc_no number, comm_details xmltype ); |
| insert into acc_comm_log values ( 1, xmltype( '<CommRecord> <CommType>EMAIL</CommType> <CommDate>3/11/2005</CommDate> <CommText>Dear Mr Smith</CommText> </CommRecord>') ) / insert into acc_comm_log values ( 2, xmltype( '<CommRecord> <CommType>LETTER</CommType> <CommDate>3/12/2005</CommDate> <CommText>Dear Mr Jackson</CommText> </CommRecord>') ); insert into acc_comm_log values ( 3, xmltype( '<CommRecord> <CommType>PHONE</CommType> <CommDate>3/10/2005</CommDate> <CommText>Dear Ms Potter</CommText> </CommRecord>') ); |
| SQL> l 1 select acc_no, 2 XMLQuery( 3 'for $i in /CommRecord 4 where $i/CommType != "EMAIL" 5 order by $i/CommType 6 return $i/CommDate' 7 passing by value COMM_DETAILS 8 returning content) XDetails 9 from acc_comm_log 10 / ACC_NO XDETAILS ---------- ------------------------------ 1 2 <CommDate>3/12/2005</CommDate> 3 <CommDate>3/10/2005</CommDate> |
| 1 select t.column_value 2 from acc_comm_log a, 3 xmltable ( 4 'for $root in $date 5 where $root/CommRecord/CommType!="EMAIL" 6 return $root/CommRecord/CommDate/text()' 7 passing a.comm_details as "date" 8* ) t SQL> / COLUMN_VALUE --------------------- 3/12/2005 3/10/2005 |
此示例演示了如何将常规的 SQL 语句用于 XML 查询所返回的 XML 表。查询按照非常结构化的 FLOWR 模式来指定命令。
XQuery 与 XMLTable 的对比
既然您已经了解了在常规 SQL 查询中使用 XML 的两种方法,就让我们来看这二种方法适用的情形。
第一种方法 XQuery 允许您获取 XMLType 形式的数据,在任何支持它的程序或应用程序中都可以将其作为 XML 来处理。在您所看到的示例中,帐户数据的结果输出是 XML 格式,而您可以使用任何工具(不必是关系型工具)来处理和显示这些数据。第二种方法 XMLTable 结合了常规 SQL 和 XML 的功能。帐户数据的结果输出不是 XML 格式,而是关系型数据。
注意两个案例中的源代码都是 XML,但是 XQuery 使用 XMLType 来表示 XML 格式的数据,而 XMLTable 将其表示为关系表,可以像常规表一样进行处理。这种功能非常适用于要输出表的现有程序,它引入了 XML 的特性。
XML 在预先不太了解确切的数据结构的场合中非常有用。在以上示例中,根据不同模式,通信记录也不相同。如果是电子邮件,则属性可能是接收方的电子邮件地址、回复地址、任何复本(cc:、bcc: 等等)、消息的文本等等。如果是电话呼叫,则属性是所呼叫的电话号码、号码的类型(家庭、工作、移动电话等等)、应答者、留下的语音邮件等等。如果您要设计一个包含所有可能的属性类型的表,则它会包括很多列,并且极其冗长,造成读取困难。但是,如果您只有一个 XMLType 列,则可以将所有内容填在那里,但仍然保持通信类型的独特属性。查询仍然可以使用简单的 SQL 接口,使应用程序的开发变得轻而易举。