使用XMLELEMENT构建XML-ORACLE SQL 11g查询

使用XMLELEMENT构建XML-ORACLE SQL 11g查询,sql,xml,oracle,oracle11g,Sql,Xml,Oracle,Oracle11g,我正在尝试使用SQL查询Oracle创建以下XML: <Changes> <Description>Some static test</Description> <Notes>Some static test</Notes> <UserChange> <Operation>Static Text</Operation> <User>VALUE

我正在尝试使用SQL查询Oracle创建以下XML:

 <Changes>
   <Description>Some static test</Description>
   <Notes>Some static test</Notes>

   <UserChange>
      <Operation>Static Text</Operation>
      <User>VALUE from Table - record #1</User>
      <BusinessSource>VALUE from Table #1</BusinessSource>
      <ApplicationRole>VALUE from Table #1</ApplicationRole>
   </UserChange>
    <UserChange>
      <Operation>Static Text</Operation>
      <User>VALUE from Table - record #2</User>
      <BusinessSource>VALUE from Table #2</BusinessSource>
      <ApplicationRole>VALUE from Table #2</ApplicationRole>
   </UserChange>
    <UserChange>
      <Operation>Static Text</Operation>
      <User>VALUE from Table - record #3</User>
      <BusinessSource>VALUE from Table #3</BusinessSource>
      <ApplicationRole>VALUE from Table #3</ApplicationRole>
   </UserChange>   
</Changes>
我想编写一个查询,根据表中的值创建动态XML。 例如: 查询应仅获取user='test1'处的值,输出为以下XML:

<Changes>
   <Description>Some static test</Description>
   <Notes>Some static test</Notes>

   <UserChange>
      <Operation>Static Text</Operation>
      <User>user1</User>
      <BusinessSource>src1</BusinessSource>
      <ApplicationRole>role1</ApplicationRole>
   </UserChange>
   <UserChange>
      <Operation>Static Text</Operation>
      <User>user1</User>
      <BusinessSource>src1</BusinessSource>
      <ApplicationRole>role1</ApplicationRole>
   </UserChange>
   <UserChange>
      <Operation>Static Text</Operation>
      <User>user1</User>
      <BusinessSource>src1</BusinessSource>
      <ApplicationRole>role2</ApplicationRole>
   </UserChange>   
</Changes>
我需要迭代其他值,使它们成为完整XML的一部分

谢谢你的帮助


谢谢

我找到了一个解决方案:

select XMLElement("Changes", 
              XMLElement("Description", 'sometext'),
              XMLElement("Notes", 'sometext'),
              XMLElement("FulfillmentDate", 'Some Date'),
                  XMLAgg(XML_CANDIDATE) ).GETSTRINGVAL() RESULTS

from 
(

select XMLAGG(
        XMLElement("UserChange",
        XMLElement("Operation", 'sometext'),
        XMLElement("User", 'sometext'),
        XMLElement("BusinessSource", 'sometext'),
        XMLElement("ApplicationRole", 'sometext')))  XML_CANDIDATE
from
table);

对于未来的读者,这里有一些开源编程解决方案,以OP的数据需求为例,将SQL查询转换为XML文档

下面的代码示例不限于任何数据库SQL方言,即,可使用以下特定于Oracle的相应连接模块传输到其他RDBMS

对于使用Python和lxml模块的Python:

import os
import cx_Oracle
import lxml.etree as ET

# Set current directory
cd = os.path.dirname(os.path.abspath(__file__))

# DB CONNECTION AND QUERY
db = cx_Oracle.connect("uid/pwd@database")    
cur = db.cursor()
cur.execute("SELECT * FROM OracleData where user='test1'")

# WRITING XML FILE
root = ET.Element('Changes')
DescNode = ET.SubElement(root, "Description").text = 'Some static test'    
NotesNode = ET.SubElement(root, "Notes").text = 'Some static test'  

# LOOPING THROUGH QUERY RESULTS TO WRITE CHILD ELEMENTS 
for row in cur.fetchall():
    UCNode = ET.SubElement(root, "UserChange")
    ET.SubElement(UCNode, "Operation").text = 'Static Text'    
    ET.SubElement(UCNode, "User").text = row[1]
    ET.SubElement(UCNode, "BusinessSource").text = row[2]    
    ET.SubElement(UCNode, "ApplicationRole").text = row[3]   

# CLOSE CURSOR AND DATABASE
cur.close()
db.close()

tree_out = (ET.tostring(root, pretty_print=True, xml_declaration=True, encoding="UTF-8"))

xmlfile = open(os.path.join(cd, 'OracleXML.xml'),'wb')
xmlfile.write(tree_out)
xmlfile.close()
用于PHP使用和DOMDocument

// Set current directory
$cd = dirname(__FILE__);

// create a dom document with encoding utf8 
$domtree = new DOMDocument('1.0', 'UTF-8');
$domtree->formatOutput = true;
$domtree->preserveWhiteSpace = false;

// Opening db connection
$db_username = "your_username";
$db_password = "your_password";
$db = "oci:dbname=your_sid";

try {
    $dbh = new PDO($db,$db_username,$db_password);          
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $sql = "SELECT * FROM OracleData where user='test1'";    
    $STH = $dbh->query($sql);    
    $STH->setFetchMode(PDO::FETCH_ASSOC); 
}

catch(PDOException $e) {  
    echo $e->getMessage();
    exit;
}

/* create the root element of the xml tree */
$xmlRoot = $domtree->createElement("Changes");
$xmlRoot = $domtree->appendChild($xmlRoot);

$DescNode = $xmlRoot->appendChild($domtree->createElement('Description',  'Some static test'));
$NotesNode = $xmlRoot->appendChild($domtree->createElement('Notes',  'Some static test'));

/* loop query results through child elements */
while($row = $STH->fetch()) {  

    $UCNode = $xmlRoot->appendChild($domtree->createElement('UserChange'));

    $operationNode = $UCNode->appendChild($domtree->createElement('Operation', 'Some static text'));
    $userNode = $UCNode->appendChild($domtree->createElement('User', $row['USER']));
    $sourceNode = $UCNode->appendChild( $domtree->createElement('BusienssSource', $row['SOURCE']));
    $roleNode = $UCNode->appendChild($domtree->createElement('ApplicationRole', $row['ROLE']));

}

file_put_contents($cd. "/OracleXML.xml", $domtree->saveXML());

# Closing db connection
$dbh = null;
exit;
对于使用R和XML包:

library(XML)
library(ROracle)

# SET CURRENT DIRECTORY   
setwd("C:\\Path\\To\\R\\Script")

# OPEN DATABASE AND QUERY
conn <-dbConnect(drv, username = "", password = "", dbname = "")
df <- dbGetQuery(conn, "select * from OracleData where user= 'test1';")
dbDisconnect(conn)

# CREATE XML FILE
doc = newXMLDoc()
root = newXMLNode("Changes", doc = doc)
descNode = newXMLNode("Description", "Some static test", parent = root)
notesNode = newXMLNode("Notes", "Some static test", parent = root)

# WRITE XML NODES AND DATA
for (i in 1:nrow(df)){
  UCNode = newXMLNode("UserChange", parent = root)

  operationNode = newXMLNode("Operation", "Some static text", parent = UCNode)
  userNode = newXMLNode("User", df$USER[i], parent = UCNode)
  sourceNode = newXMLNode("BusinessSource", df$SOURCE[i], parent = UCNode)
  roleNode = newXMLNode("ApplicationRole", df$ROLE[i], parent = UCNode)
}

# OUTPUT XML CONTENT TO FILE
saveXML(doc, file="OracleXML.xml")

您可以使用以下查询:

select xmlelement("Changes",
           xmlforest(
               'Some Static Text' "Description"
             , 'Some Static Text' "Notes")
         , xmlagg(
             xmlelement("UserChange",
               xmlforest('Static Text' "Operation",
                         "USER" "User",
                         SOURCE "BusinessSource",
                         ROLE "ApplicationRole")
             )
           )
       ),getclobval()
  from table
 where "USER" = 'test1';

但是请记住,XMLAGG函数是一个聚合函数。在这种情况下,表中的每个选定列都包含在聚合中,因此不需要GROUPBY。然而,若要在XMLAGG之外包含表中的某些列,则需要将它们包含在GROUPBY语句中。此外,由于用户是一个保留字,因此需要用双引号将其括起来作为列引用。

您使用或提供了哪些语言:C、Java、PHP、Python、R、SAS、MS Excel/Access VBA?作为一种特殊用途的语言,SQL是有限的,并且在不同的方言中有所不同。但所有这些与其他工具一起可以获取查询结果、循环记录和生成XML文档,甚至可以使用XSLT。
library(XML)
library(ROracle)

# SET CURRENT DIRECTORY   
setwd("C:\\Path\\To\\R\\Script")

# OPEN DATABASE AND QUERY
conn <-dbConnect(drv, username = "", password = "", dbname = "")
df <- dbGetQuery(conn, "select * from OracleData where user= 'test1';")
dbDisconnect(conn)

# CREATE XML FILE
doc = newXMLDoc()
root = newXMLNode("Changes", doc = doc)
descNode = newXMLNode("Description", "Some static test", parent = root)
notesNode = newXMLNode("Notes", "Some static test", parent = root)

# WRITE XML NODES AND DATA
for (i in 1:nrow(df)){
  UCNode = newXMLNode("UserChange", parent = root)

  operationNode = newXMLNode("Operation", "Some static text", parent = UCNode)
  userNode = newXMLNode("User", df$USER[i], parent = UCNode)
  sourceNode = newXMLNode("BusinessSource", df$SOURCE[i], parent = UCNode)
  roleNode = newXMLNode("ApplicationRole", df$ROLE[i], parent = UCNode)
}

# OUTPUT XML CONTENT TO FILE
saveXML(doc, file="OracleXML.xml")
select xmlelement("Changes",
           xmlforest(
               'Some Static Text' "Description"
             , 'Some Static Text' "Notes")
         , xmlagg(
             xmlelement("UserChange",
               xmlforest('Static Text' "Operation",
                         "USER" "User",
                         SOURCE "BusinessSource",
                         ROLE "ApplicationRole")
             )
           )
       ),getclobval()
  from table
 where "USER" = 'test1';