2013-01-02 4 views
0

xml에서 SQL 데이터를 추출하라는 제안을 알려주십시오.xml에서 sql 데이터 추출

<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> 

하여 추출 된 데이터는 다음과 같이 보일 것이다 :

(MARKET_NAME = 'Chicago' or MARKET_NAME = 'BOSTON') and 
(RANK = 1 or RANK = 2) and 
(current_date between start_date and End_Date) and 
CUME > 20 and 
DMA_NAME like '%ABC%' 

은 .. 내가 당신의 소중한 팁을 알고

하자 샘플 XML은 아래와 같이 CLOB과 같은 절차에 대한 입력으로 제공 될 것이다

미리 감사드립니다.

+0

[** 당신은 지금까지 어떤 시도를 했습니까?] (http://www.whathaveyoutried.com) - 또한 어떤 프로그래밍 언어를 원하십니까? 그리고이 데이터베이스 시스템은 무엇입니까? –

+0

이 XML은 PL/SQL 프로 시저에 CLOB 객체로 전달됩니다. 필자는 XML을 읽고 주어진 쿼리를 프레임 화해야합니다. – Krishnakumar

+0

DB는 오라클 11g – Krishnakumar

답변

2

한 가지 방법은 XSL 스타일 시트입니다.

하지만 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> 

다음 XSL (이것은 단지 샘플입니다 당신은 당신을 위해 그것의 단지 기본적인 선발이 개선해야합니다.!)

<?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> 

예 : XSL 밖으로

는로 저장 XMLTYPE :

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"/> 
... 

이제 우리는을 얻기 위해 입력 XML에 XMLTYPE의 transform 기능을 사용 결과 :

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%') 
관련 문제