【问题标题】:How do I convert SQL to XML?如何将 SQL 转换为 XML?
【发布时间】:2018-03-28 16:26:18
【问题描述】:

我正在尝试将 SQL 输出为 XML 以匹配以下格式的确切格式

<?xml version="1.0" encoding="utf-8"?>
<ProrateImport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schema.aldi-
sued.com/Logistics/Shipping/ProrateImport/20151009">
  <Prorates>
    <Prorate>
      <OrderTypeId>1</OrderTypeId>
      <DeliveryDate>2015-10-12T00:00:00+02:00</DeliveryDate>
      <DivNo>632</DivNo>
      <ProrateUnit>1</ProrateUnit>
      <ProrateProducts>
      <ProrateProduct ProductCode="8467">
          <ProrateItems>
            <ProrateItem StoreNo="1">
              <Quantity>5</Quantity>
            </ProrateItem>
            <ProrateItem StoreNo="2">
              <Quantity>5</Quantity>
            </ProrateItem>
            <ProrateItem StoreNo="3">
              <Quantity>5</Quantity>
            </ProrateItem>
          </ProrateItems>
        </ProrateProduct>
      </ProrateProducts>
    </Prorate>
  </Prorates>
</ProrateImport>

这是我的查询:

SELECT 
    OrderTypeID,
    DeliveryDate, DivNo,
    ProrateUnit,
    (SELECT  
         ProductOrder [@ProductCode],
         (SELECT 
              ProrateItem [@StoreNo],
              CAST(Quantity AS INT) [Quantity]
          FROM 
              ##Result2 T3
          WHERE
              T3.DivNo = T2.DivNo 
              AND T3.DivNo = T1.DivNo 
              AND T3.DeliveryDate = T2.DeliveryDate 
              AND T3.DeliveryDate = T1.DeliveryDate
              AND T3.ProductOrder = t2.ProductOrder
          FOR XML PATH('ProrateItem'), TYPE, ROOT('ProrateItems')
         )
     FROM 
         ##Result2 T2
     WHERE
         T2.DivNo = T1.DivNo 
         AND T2.DeliveryDate = T1.DeliveryDate
     FOR XML PATH('ProrateProduct'), TYPE, ROOT('ProrateProducts')
    )
FROM 
    ##Result2 T1
GROUP BY 
    OrderTypeID, DeliveryDate, DivNo, ProrateUnit
FOR XML PATH('Prorate'), TYPE, ROOT('Prorates')

如何添加以下内容并将 ProrateImport/20151009" 更改为当前日期?

<?xml version="1.0" encoding="utf-8"?>
<ProrateImport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schema.aldi-
sued.com/Logistics/Shipping/ProrateImport/20151009">

这是我第一次使用 XML

【问题讨论】:

    标签: sql-server xml tsql namespaces processing-instruction


    【解决方案1】:

    我不确定我是否理解。您是否自己创建了第一个 XML,只需要添加最后一个脚本?

    DECLARE @XMLHEADER nvarchar(max)
    
    SET @XMLHEADER = '<?xml version="1.0" encoding="utf-8"?>
    <ProrateImport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schema.aldi-sued.com/Logistics/Shipping/ProrateImport/'+convert(varchar(8),getdate(),112)+'"
    >'
    
    select @xmlheader
    

    然后您只需从您的 select 语句中添加其余的输出。

    【讨论】:

      【解决方案2】:

      有几个问题:

      • 如何引入命名空间?
      • 如何动态引入命名空间
      • 如何添加&lt;?xml ?&gt; 指令
      • 两级根 (&lt;ProrateImport&gt;&lt;Prorate&gt;)

      命名空间

      您必须使用 WITH XMLNAMESSPACES 为您的查询引入命名空间。

      提示: xmlns 是由DEFAULT 引入的,xsi 命名空间将通过使用ELEMENTS XSINIL 自动引入:

      WITH XMLNAMESPACES('http://www.w3.org/2001/XMLSchema' AS xsd
                         ,DEFAULT 'http://schema.aldi-sued.com/Logistics/Shipping/ProrateImport/20151009')
      SELECT 1 AS Dummy 
      FOR XML PATH('rowElement'), ELEMENTS XSINIL, ROOT('root')
      

      结果

      <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xmlns="http://schema.aldi-sued.com/Logistics/Shipping/ProrateImport/20151009" 
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <rowElement>
          <Dummy>1</Dummy>
        </rowElement>
      </root>
      

      注意:命名空间必须按字面意思说明。没有计算,没有变量!

      动态命名空间

      这是 - 开箱即用 - 不可能的。但是您可以使用动态创建的 SQL 并使用 EXEC 来获得结果。只需像上面一样创建语句

      DECLARE @cmd VARCHAR(MAX)=
      '
      WITH XMLNAMESPACES(''http://www.w3.org/2001/XMLSchema'' AS xsd
                         ,DEFAULT ''http://schema.aldi-sued.com/Logistics/Shipping/ProrateImport/' + CONVERT(VARCHAR(8),GETDATE(),112)  + ''')
      SELECT 1 AS Dummy 
      FOR XML PATH(''rowElement''), ELEMENTS XSINIL, ROOT(''root'')';
      
      PRINT @cmd
      EXEC(@cmd);
      

      结果

      <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xmlns="http://schema.aldi-sued.com/Logistics/Shipping/ProrateImport/20171019" 
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <rowElement>
          <Dummy>1</Dummy>
        </rowElement>
      </root>
      

      指令

      指令不能引入 XML。 SQL-Server 将省略任何 &lt;?xml ?&gt; 指令!这只能在字符串级别完成:

      DECLARE @cmd VARCHAR(MAX)=
      '
      WITH XMLNAMESPACES(''http://www.w3.org/2001/XMLSchema'' AS xsd
                         ,DEFAULT ''http://schema.aldi-sued.com/Logistics/Shipping/ProrateImport/' + CONVERT(VARCHAR(8),GETDATE(),112)  + ''')
      SELECT(
      SELECT 1 AS Dummy 
      FOR XML PATH(''rowElement''), ELEMENTS XSINIL, ROOT(''root'')) AS MyResult';
      
      CREATE TABLE #resultTable(MyXmlAsString VARCHAR(MAX))
      INSERT INTO #resultTable(MyXmlAsString)
      EXEC(@cmd);
      
      SELECT '<?xml version="1.0" encoding="utf-8"?>' + MyXmlAsString
      FROM #resultTable;
      

      结果

      <?xml version="1.0" encoding="utf-8"?>
      <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xmlns="http://schema.aldi-sued.com/Logistics/Shipping/ProrateImport/20171019" 
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">
          <rowElement>
              <Dummy>1</Dummy>
          </rowElement>
      </root>
      

      两级根

      您可以嵌套两个FOR XML 语句来实现:

      WITH XMLNAMESPACES(DEFAULT 'blah')
      SELECT
      (
          SELECT 1 AS Dummy
          FOR XML PATH('rowElement'),ROOT('innerRoot'),TYPE
      )
      FOR XML PATH('outerRoot');
      

      但令人讨厌的是,每个子选择都会一遍又一遍地引入命名空间。没有错,但很烦人!众所周知的Microsoft connect issue。请登录并投票!结果:

      <outerRoot xmlns="blah">
        <innerRoot xmlns="blah">   <!--Here's the second xmlns! -->
          <rowElement>
            <Dummy>1</Dummy>
          </rowElement>
        </innerRoot>
      </outerRoot>
      

      您的解决方案

      解释完所有这些后,我建议创建没有任何命名空间或声明的 XML(您已经在做的事情!),然后将结果转换为 NVARCHAR(MAX) 并在字符串级别添加页眉和结束页脚。这很丑陋,但在你的情况下是唯一的方法。

      提示:如果不丢失指令,您将无法在 SQL Server 中以原生 XML 类型存储最终结果。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-07
        • 2015-06-02
        • 1970-01-01
        • 2011-04-28
        • 2013-07-30
        相关资源
        最近更新 更多