Stored procedures 从xml中提取sql数据

Stored procedures 从xml中提取sql数据,stored-procedures,plsql,oracle11g,extract,Stored Procedures,Plsql,Oracle11g,Extract,请告诉我您对从xml提取SQL数据的建议。示例xml如下所示,作为CLOB作为过程的输入: <filter> <and> <or> <equals field="MARKET_NAME" value="Chicago"/> <equals field="MARKET_NAME" value="BOSTON"/> </or> <or> <equa

请告诉我您对从xml提取SQL数据的建议。示例xml如下所示,作为CLOB作为过程的输入:

<filter>
  <and>
    <or>
      <equals field="MARKET_NAME" value="Chicago"/>
      <equals field="MARKET_NAME" value="BOSTON"/>
    </or>
    <or>
      <equals field="RANK" value="1"/>
      <equals field="RANK" value="2"/>
    </or>
    <between field="current_data" arg1="start_date" arg2="End_date"/>
    <gt field="CUME" value="20"/>
    <like field="DMA_NAME" value="%ABC%"/>
  </and>
</filter>
让我知道你的宝贵建议


提前感谢

一种方法是XSL样式表

但我会在XML中添加数据类型。e、 g

<filter>
    <and>
        <or>
            <equals field="MARKET_NAME" value="Chicago" datatype="string"/>
            <equals field="MARKET_NAME" value="BOSTON" datatype="string"/>
        </or>
        <or>
            <equals field="RANK" value="1" datatype="number"/>
            <equals field="RANK" value="2" datatype="number"/>
        </or>
        <between field="current_data" arg1="start_date" arg2="End_date" datatype="field"/>
        <between field="foo" arg1="20121230" arg2="20130101 01:12:23" datatype="date"/>
        <gt field="CUME" value="20" datatype="number"/>
        <like field="DMA_NAME" value="%ABC%"  datatype="string"/>
    </and>
</filter>

-另外:您想用什么编程语言来实现这一点?这是什么数据库系统?这个XML将作为CLOB对象传递给PL/SQL过程。我需要读取XML并按照给定的框架构造所提到的查询。我曾尝试在plsql块中使用(XML.EXTRACT)从XML中提取值,成功了,我现在想要的是基于XML输入动态构造sql语句:请参考microsoft的以下url。这将帮助您从XML中提取数据,谢谢
<filter>
    <and>
        <or>
            <equals field="MARKET_NAME" value="Chicago" datatype="string"/>
            <equals field="MARKET_NAME" value="BOSTON" datatype="string"/>
        </or>
        <or>
            <equals field="RANK" value="1" datatype="number"/>
            <equals field="RANK" value="2" datatype="number"/>
        </or>
        <between field="current_data" arg1="start_date" arg2="End_date" datatype="field"/>
        <between field="foo" arg1="20121230" arg2="20130101 01:12:23" datatype="date"/>
        <gt field="CUME" value="20" datatype="number"/>
        <like field="DMA_NAME" value="%ABC%"  datatype="string"/>
    </and>
</filter>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
    exclude-result-prefixes="xd"
    version="1.0">
    <xsl:output method="text"/>

    <xsl:template name="string-replace-all">
        <xsl:param name="text"/>
        <xsl:param name="replace"/>
        <xsl:param name="by"/>
        <xsl:choose>
            <xsl:when test="contains($text,$replace)">
                <xsl:value-of select="substring-before($text,$replace)"/>
                <xsl:value-of select="$by"/>
                <xsl:call-template name="string-replace-all">
                    <xsl:with-param name="text" select="substring-after($text,$replace)"/>
                    <xsl:with-param name="replace" select="$replace"/>
                    <xsl:with-param name="by" select="$by"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$text"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template name="processDatatype">
        <xsl:param name="value" />
        <xsl:param name="datatype" />
        <xsl:choose>
            <xsl:when test="$datatype = 'string'">
                <xsl:text>&apos;</xsl:text>
                <xsl:call-template name="string-replace-all">
                    <xsl:with-param name="text" select="$value"/>
                    <xsl:with-param name="replace" select='"&apos;"'/>
                    <xsl:with-param name="by" select='"&apos;&apos;"'/>
                </xsl:call-template>
                <xsl:text>&apos;</xsl:text>
            </xsl:when>
            <xsl:when test="$datatype = 'date'">
                <xsl:text>to_date(&apos;</xsl:text>
                <xsl:value-of select="$value"/>
                <xsl:text>&apos;,&apos;yyyymmdd hh24:mi:ss&apos;)</xsl:text>
            </xsl:when>
            <xsl:otherwise><xsl:value-of select="$value"/></xsl:otherwise>
        </xsl:choose>

    </xsl:template>

    <xsl:template name="gt">
        <xsl:value-of select="@field"/>
        <xsl:text> &gt; </xsl:text>
        <xsl:call-template name="processDatatype">
            <xsl:with-param name="value"><xsl:value-of select="@value"/></xsl:with-param>
            <xsl:with-param name="datatype"><xsl:value-of select="@datatype"/></xsl:with-param>
        </xsl:call-template>
    </xsl:template>

    <xsl:template name="lt">
        <xsl:value-of select="@field"/>
        <xsl:text> &lt; </xsl:text>
        <xsl:call-template name="processDatatype">
            <xsl:with-param name="value"><xsl:value-of select="@value"/></xsl:with-param>
            <xsl:with-param name="datatype"><xsl:value-of select="@datatype"/></xsl:with-param>
        </xsl:call-template>
    </xsl:template>

    <xsl:template name="between">
        <xsl:value-of select="@field"/>
        <xsl:text> between </xsl:text>
        <xsl:call-template name="processDatatype">
            <xsl:with-param name="value"><xsl:value-of select="@arg1"/></xsl:with-param>
            <xsl:with-param name="datatype"><xsl:value-of select="@datatype"/></xsl:with-param>
        </xsl:call-template>
        <xsl:text> and </xsl:text>
        <xsl:call-template name="processDatatype">
            <xsl:with-param name="value"><xsl:value-of select="@arg2"/></xsl:with-param>
            <xsl:with-param name="datatype"><xsl:value-of select="@datatype"/></xsl:with-param>
        </xsl:call-template>
    </xsl:template>

    <xsl:template name="like">
        <xsl:value-of select="@field"/>
        <xsl:text> like </xsl:text>
        <xsl:call-template name="processDatatype">
            <xsl:with-param name="value"><xsl:value-of select="@value"/></xsl:with-param>
            <xsl:with-param name="datatype"><xsl:value-of select="@datatype"/></xsl:with-param>
        </xsl:call-template>
    </xsl:template>

    <xsl:template name="equals">
        <xsl:value-of select="@field"/>
        <xsl:text> = </xsl:text>
        <xsl:call-template name="processDatatype">
            <xsl:with-param name="value"><xsl:value-of select="@value"/></xsl:with-param>
            <xsl:with-param name="datatype"><xsl:value-of select="@datatype"/></xsl:with-param>
        </xsl:call-template>
    </xsl:template>


    <xsl:template name="and">
        <xsl:for-each select="*">
            <xsl:if test="position() != 1">
                <xsl:text>and </xsl:text>
            </xsl:if>
            <xsl:choose>
                <xsl:when test="name() = 'like'">
                    <xsl:text>(</xsl:text>
                    <xsl:call-template name="like" />
                    <xsl:text>)&#10;</xsl:text>
                </xsl:when>
                <xsl:when test="name() = 'gt'">
                    <xsl:text>(</xsl:text>
                    <xsl:call-template name="gt" />
                    <xsl:text>)&#10;</xsl:text>
                </xsl:when>
                <xsl:when test="name() = 'lt'">
                    <xsl:text>(</xsl:text>
                    <xsl:call-template name="lt" />
                    <xsl:text>)&#10;</xsl:text>
                </xsl:when>
                <xsl:when test="name() = 'equals'">
                    <xsl:text>(</xsl:text>
                    <xsl:call-template name="equals" />
                    <xsl:text>)&#10;</xsl:text>
                </xsl:when>
                <xsl:when test="name() = 'between'">
                    <xsl:text>(</xsl:text>
                    <xsl:call-template name="between" />
                    <xsl:text>)&#10;</xsl:text>
                </xsl:when>
                <xsl:when test="name() = 'or'">
                    <xsl:text>(</xsl:text>
                    <xsl:call-template name="or" />
                    <xsl:text>)&#10;</xsl:text>
                </xsl:when>
            </xsl:choose>
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="or">
        <xsl:for-each select="*">
            <xsl:if test="position() != 1">
                <xsl:text>or </xsl:text>
            </xsl:if>
            <xsl:choose>
                <xsl:when test="name() = 'like'">
                    <xsl:text>(</xsl:text>
                    <xsl:call-template name="like" />
                    <xsl:text>)&#10;</xsl:text>
                </xsl:when>
                <xsl:when test="name() = 'gt'">
                    <xsl:text>(</xsl:text>
                    <xsl:call-template name="gt" />
                    <xsl:text>)&#10;</xsl:text>
                </xsl:when>
                <xsl:when test="name() = 'lt'">
                    <xsl:text>(</xsl:text>
                    <xsl:call-template name="lt" />
                    <xsl:text>)&#10;</xsl:text>
                </xsl:when>
                <xsl:when test="name() = 'equals'">
                    <xsl:text>(</xsl:text>
                    <xsl:call-template name="equals" />
                    <xsl:text>)&#10;</xsl:text>
                </xsl:when>
                <xsl:when test="name() = 'between'">
                    <xsl:text>(</xsl:text>
                    <xsl:call-template name="between" />
                    <xsl:text>)&#10;</xsl:text>
                </xsl:when>
                <xsl:when test="name() = 'and'">
                    <xsl:text>(</xsl:text>
                    <xsl:call-template name="and" />
                    <xsl:text>)&#10;</xsl:text>
                </xsl:when>
            </xsl:choose>
        </xsl:for-each>
    </xsl:template>

    <xsl:template match="/filter">
        <xsl:text>where </xsl:text>
        <xsl:for-each select="*">
            <xsl:choose>
                <xsl:when test="name() = 'and'">
                    <xsl:call-template name="and" />
                </xsl:when>
                <xsl:when test="name() = 'or'">
                    <xsl:call-template name="or" />
                </xsl:when>
            </xsl:choose>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
SQL> select * from xsl;

NAME
--------------------
XSL
--------------------------------------------------------------------------------
xml_to_sql
<?xml version="1.0" encoding="WINDOWS-1252"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xd="http:
//www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xd" version="1.0">
  <xsl:output method="text"/>
  <xsl:template name="string-replace-all">
    <xsl:param name="text"/>
...
SQL> select dbms_xmlgen.convert(xmltype('<?xml-stylesheet type="text/xsl" href="test.xsl"?>
  2  <filter>
  3      <and>
  4          <or>
  5              <equals field="MARKET_NAME" value="Chicago" datatype="string"/>
  6              <equals field="MARKET_NAME" value="BOSTON" datatype="string"/>
  7          </or>
  8          <or>
  9              <equals field="RANK" value="1" datatype="number"/>
 10              <equals field="RANK" value="2" datatype="number"/>
 11          </or>
 12          <between field="current_data" arg1="start_date" arg2="End_date" datatype="field"/>
 13          <between field="foo" arg1="20121230" arg2="20130101 01:12:23" datatype="date"/>
 14          <gt field="CUME" value="20" datatype="number"/>
 15          <like field="DMA_NAME" value="%AB&apos;C%"  datatype="string"/>
 16      </and>
 17  </filter>').transform(xsl.xsl).getclobval(), 1)
 18  from xsl
 19  /

DBMS_XMLGEN.CONVERT(XMLTYPE('<
--------------------------------------------------------------------------------
where ((MARKET_NAME = 'Chicago')
or (MARKET_NAME = 'BOSTON')
)
and ((RANK = 1)
or (RANK = 2)
)
and (current_data between start_date and End_date)
and (foo between to_date('20121230','yyyymmdd hh24:mi:ss') and to_date('20130101
 01:12:23','yyyymmdd hh24:mi:ss'))
and (CUME > 20)
and (DMA_NAME like '%AB''C%')