【问题标题】:Delete empty node in XML file using SQL使用 SQL 删除 XML 文件中的空节点
【发布时间】:2015-04-13 06:18:44
【问题描述】:

您好,我在 SQL 中使用 XML Auto 创建了 XML 文件。该文件是根据六个表中的记录创建的。如果关联表中没有值,则创建一个空节点。有没有办法删除 SSIS 或 SQL 中的空节点?

下面是使用的查询

select
(select 

      Opp.OPPORTUNITYID as OPPORTUNITYID,
      Opp.CREATEDATE as RequestDate,
      (select USERNAME from sysdba.USERINFO where USERID=Opp.ACCOUNTMANAGERID) as RepName,
      (select Account from sysdba.ACCOUNT where ACCOUNTID=Opp.ACCOUNTID )as Account,
      (select ACCOUNTID from sysdba.ACCOUNT where ACCOUNTID=Opp.ACCOUNTID ) as AccountID,
      (select MDRPID from sysdba.ACCOUNT where ACCOUNTID=Opp.ACCOUNTID ) as MDRPID,
      (select Coalesce(acc1.accountid,acc.accountid) from sysdba.ACCOUNT  acc  left  join sysdba.ACCOUNT acc1 on acc.UNIVERSITYID = acc1.accountid where acc.ACCOUNTID=Opp.ACCOUNTID ) as UniversityID,
      (select Coalesce(acc1.account,acc.account) from sysdba.ACCOUNT  acc  left  join sysdba.ACCOUNT acc1 on acc.UNIVERSITYID = acc1.accountid where acc.ACCOUNTID=Opp.ACCOUNTID ) as University,
      (Opp.STARTDATE) as StartDate,
      (opp.enddate) as EndDate,
     Coalesce ( opp.PROMOCODE,'') as Promocode,
      Opp.MICROSITEURLKEY as MicrositeURLKey,
      opp.modifydate as ModifyDate,
      (select GUID from sysdba.ACCOUNT where ACCOUNTID=Opp.ACCOUNTID ) as LocationID,
      OppProduct.OPPPRODUCTID as OppProductID,
        OppProduct.PRICE as Price,
      OppProduct.CALCPRICE as CalculatedPrice,
      OppProduct.discount as Discount,
     (select pro.ISBN from sysdba.C_PRODUCT pro join sysdba.OPPORTUNITY_PRODUCT opppro on pro.C_PRODUCTID=opppro.PRODUCTID where opppro.OPPPRODUCTID=OppProduct.OPPPRODUCTID ) as ISBN,
      (select pro.TITLE from sysdba.C_PRODUCT pro join sysdba.OPPORTUNITY_PRODUCT opppro on pro.C_PRODUCTID=opppro.PRODUCTID where opppro.OPPPRODUCTID=OppProduct.OPPPRODUCTID ) as Title,
      AccCourse.ACCOUNTCOURSEID  AS ACCOUNTCOURSEID,
      AccCourse.COURSENAME as CourseName,
      AccCourse.MDRCLGCOURSE as CLGCourse,
      Contact.CONTACTID  as CONTACTID,
      Contact.FIRSTNAME as FirstName,
      Contact.LASTNAME as LastName,
      Contact.EMAIL as Email


from sysdba.OPPORTUNITY Opp
 join sysdba.OPPORTUNITY_PRODUCT OppProduct on Opp.OPPORTUNITYID = OppProduct.OPPORTUNITYID
left join sysdba.C_PRODUCT Product on OppProduct.PRODUCTID = Product.C_PRODUCTID
left join sysdba.OPPPRODUCTCOURSE ProductCourse on OppProduct.OPPPRODUCTID = ProductCourse.OPPPRODUCTID
left join sysdba.OPPORTUNITYCOURSE OppCourse on ProductCourse.OPPORTUNITYCOURSEID = OppCourse.OPPORTUNITYCOURSEID
left join sysdba.ACCOUNTCOURSE AccCourse on OppCourse.ACCOUNTCOURSEID = AccCourse.ACCOUNTCOURSEID
left join sysdba.OPPCOURSECONTACT OppContact on OppCourse.OPPORTUNITYCOURSEID = OppContact.OPPORTUNITYCOURSEID
left join sysdba.CONTACT contact on contact.CONTACTID=OppContact.CONTACTID
For XML AUTO, ROOT('INFO'))as col

输出:

<INFO>
  <Opp LocationID="1594743" ModifyDate="2015-04-01T23:50:01" MicrositeURLKey="O6UJ9A03XT6J" MDRPID="1594743" AccountID="A6UJ9A00OS1L" Account="Marquette University " RepName="Maggie Dolan" RequestDate="2015-04-01T23:48:07" OPPORTUNITYID="O6UJ9A03XT6J">
    <OppProduct Title="prepU for Jensen's Nursing Health Assessment: A Best Practice Approach, Ecommerce, 3 Month Access (PREPU)" ISBN="9781469895727" Price="0.0000" OppProductID="Q6UJ9A15NMSF">
      <AccCourse>
        <contact />
      </AccCourse>
    </OppProduct>
    <OppProduct Title="Lippincott CoursePoint for Nursing Health Assessment: A Best Approach, Ecommerce Version, 12 Month Access (CoursePoint)" ISBN="9781496303134" Price="0.0000" OppProductID="Q6UJ9A15NMSG">
      <AccCourse>
        <contact />
      </AccCourse>
    </OppProduct>
  </Opp>
</INFO>

如果节点为空,有没有办法删除它?例如&lt;Contact&gt;&lt;AccCourse&gt;

【问题讨论】:

标签: sql-server ssis sqlxml


【解决方案1】:

你可以像这样使用代码行

    SET @testXML.modify('delete  /INFO//*[not(@*)]')

这将删除INFO 下没有任何属性的所有节点。

完整的代码示例

    DECLARE @testXML XML
    SET @testXML=            
                   ' <INFO>
      <Opp LocationID="1594743" ModifyDate="2015-04-01T23:50:01" MicrositeURLKey="O6UJ9A03XT6J" MDRPID="1594743" AccountID="A6UJ9A00OS1L" Account="Marquette University " RepName="Maggie Dolan" RequestDate="2015-04-01T23:48:07" OPPORTUNITYID="O6UJ9A03XT6J">
        <OppProduct Title="prepU for Jensen''s Nursing Health Assessment: A Best Practice Approach, Ecommerce, 3 Month Access (PREPU)" ISBN="9781469895727" Price="0.0000" OppProductID="Q6UJ9A15NMSF">
          <AccCourse>
            <contact />
          </AccCourse>
        </OppProduct>
        <OppProduct Title="Lippincott CoursePoint for Nursing Health Assessment: A Best Approach, Ecommerce Version, 12 Month Access (CoursePoint)" ISBN="9781496303134" Price="0.0000" OppProductID="Q6UJ9A15NMSG">
          <AccCourse>
            <contact />
          </AccCourse>
        </OppProduct>
      </Opp>
    </INFO>'
    select @testXML 
    SET @testXML.modify('delete  /INFO//*[not(@*)]')
    select @testXML

【讨论】:

  • 感谢您的帮助阿伦。 XML 文件是动态创建的,请告诉我如何将文件名而不是文件内容传递给上述解决方案。
【解决方案2】:

您可以使用XML modify() 删除没有属性的节点。像这样的东西。

DECLARE @xml xml =
'<?xml version="1.0"?>
<Opp LocationID="1594743" ModifyDate="2015-04-01T23:50:01" MicrositeURLKey="O6UJ9A03XT6J" MDRPID="1594743" AccountID="A6UJ9A00OS1L" Account="Marquette University " RepName="Maggie Dolan" RequestDate="2015-04-01T23:48:07" OPPORTUNITYID="O6UJ9A03XT6J"><OppProduct Title="prepU for Jensen''s Nursing Health Assessment: A Best Practice Approach, Ecommerce, 3 Month Access (PREPU)" ISBN="9781469895727" Price="0.0000" OppProductID="Q6UJ9A15NMSF"><AccCourse><contact/></AccCourse></OppProduct><OppProduct Title="Lippincott CoursePoint for Nursing Health Assessment: A Best Approach, Ecommerce Version, 12 Month Access (CoursePoint)" ISBN="9781496303134" Price="0.0000" OppProductID="Q6UJ9A15NMSG"><AccCourse ACCOUNTCOURSEID="2"><contact/></AccCourse></OppProduct></Opp>'

SELECT @xml

SET @xml.modify('delete //AccCourse[empty(@ACCOUNTCOURSEID)]')

SELECT @xml

更多信息请参考delete (XML DML)

【讨论】:

    【解决方案3】:

    基于 Arun Gairola 的回答:

    你可以像这样使用代码行

    SET @testXML.modify('delete  /INFO//*[not(@*)]') 
    

    这将删除INFO下所有没有任何属性的节点。

    由于您的 XML 是从查询生成的,因此您可以将结果设置为变量,然后从变量中删除空节点。使用上面的 SQL,您需要执行以下操作:

    set @xml xml;
    set @xml = (
        select <columns>
        from <tables>
        For XML AUTO, ROOT('INFO')
        )
    
    set @xml.modify('delete  /INFO//*[not(@*)]')
    select @xml
    

    使用您在问题中提供的完整 sql,您需要这样做:

    set @xml xml;
    set @xml = (select 
        Opp.OPPORTUNITYID as OPPORTUNITYID,
        Opp.CREATEDATE as RequestDate,
        (select USERNAME from sysdba.USERINFO where USERID=Opp.ACCOUNTMANAGERID) as RepName,
        (select Account from sysdba.ACCOUNT where ACCOUNTID=Opp.ACCOUNTID )as Account,
        (select ACCOUNTID from sysdba.ACCOUNT where ACCOUNTID=Opp.ACCOUNTID ) as AccountID,
        (select MDRPID from sysdba.ACCOUNT where ACCOUNTID=Opp.ACCOUNTID ) as MDRPID,
        (select Coalesce(acc1.accountid,acc.accountid) from sysdba.ACCOUNT  acc  left  join sysdba.ACCOUNT acc1 on acc.UNIVERSITYID = acc1.accountid where acc.ACCOUNTID=Opp.ACCOUNTID ) as UniversityID,
        (select Coalesce(acc1.account,acc.account) from sysdba.ACCOUNT  acc  left  join sysdba.ACCOUNT acc1 on acc.UNIVERSITYID = acc1.accountid where acc.ACCOUNTID=Opp.ACCOUNTID ) as University,
        (Opp.STARTDATE) as StartDate,
        (opp.enddate) as EndDate,
        Coalesce ( opp.PROMOCODE,'') as Promocode,
        Opp.MICROSITEURLKEY as MicrositeURLKey,
        opp.modifydate as ModifyDate,
        (select GUID from sysdba.ACCOUNT where ACCOUNTID=Opp.ACCOUNTID ) as LocationID,
        OppProduct.OPPPRODUCTID as OppProductID,
        OppProduct.PRICE as Price,
        OppProduct.CALCPRICE as CalculatedPrice,
        OppProduct.discount as Discount,
        (select pro.ISBN from sysdba.C_PRODUCT pro join sysdba.OPPORTUNITY_PRODUCT opppro on pro.C_PRODUCTID=opppro.PRODUCTID where opppro.OPPPRODUCTID=OppProduct.OPPPRODUCTID ) as ISBN,
        (select pro.TITLE from sysdba.C_PRODUCT pro join sysdba.OPPORTUNITY_PRODUCT opppro on pro.C_PRODUCTID=opppro.PRODUCTID where opppro.OPPPRODUCTID=OppProduct.OPPPRODUCTID ) as Title,
        AccCourse.ACCOUNTCOURSEID  AS ACCOUNTCOURSEID,
        AccCourse.COURSENAME as CourseName,
        AccCourse.MDRCLGCOURSE as CLGCourse,
        Contact.CONTACTID  as CONTACTID,
        Contact.FIRSTNAME as FirstName,
        Contact.LASTNAME as LastName,
        Contact.EMAIL as Email
    from sysdba.OPPORTUNITY Opp
    join sysdba.OPPORTUNITY_PRODUCT OppProduct on Opp.OPPORTUNITYID = OppProduct.OPPORTUNITYID
    left join sysdba.C_PRODUCT Product on OppProduct.PRODUCTID = Product.C_PRODUCTID
    left join sysdba.OPPPRODUCTCOURSE ProductCourse on OppProduct.OPPPRODUCTID = ProductCourse.OPPPRODUCTID
    left join sysdba.OPPORTUNITYCOURSE OppCourse on ProductCourse.OPPORTUNITYCOURSEID = OppCourse.OPPORTUNITYCOURSEID
    left join sysdba.ACCOUNTCOURSE AccCourse on OppCourse.ACCOUNTCOURSEID = AccCourse.ACCOUNTCOURSEID
    left join sysdba.OPPCOURSECONTACT OppContact on OppCourse.OPPORTUNITYCOURSEID = OppContact.OPPORTUNITYCOURSEID
    left join sysdba.CONTACT contact on contact.CONTACTID=OppContact.CONTACTID
    For XML AUTO, ROOT('INFO'))
    
    set @xml.modify('delete  /INFO//*[not(@*)]')
    select @xml
    

    【讨论】:

      【解决方案4】:

      我觉得这个更好:

      modify('delete  //*[not(node())]')
      

      你也可以参考这个: Delete Empty XML nodes

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-23
        • 2017-04-10
        • 2019-01-07
        • 1970-01-01
        • 2023-04-02
        • 1970-01-01
        • 2013-02-19
        • 1970-01-01
        相关资源
        最近更新 更多