【问题标题】:Extract data values from XML column in SQL Server database从 SQL Server 数据库中的 XML 列中提取数据值
【发布时间】:2023-03-06 21:38:01
【问题描述】:

我有一个 SQL Server 数据库,其中包含一个包含 XML 列的表。我想从中提取数据,但我们在名称上使用了前缀。

这是一个例子:

<cfdi:comprobante xmlns:cfdi="" total="" tax="">
     <cfdi:sender information="" moreinformation=""/>
     <cfdi:receiver information="" moreinformation=""/>
     <cfdi:addments>
            <another:payment information="" moreinformation="">
                <another:Movements date="" description="hello" amount="100.00" contract="10"/>
                <another:Movements date="" description="hello2" amount="200.00" contract="20"/>
                <another:Movements date="" description="bye" amount="300.00" contract="30"/>
                <another:Movements date="" description="bye2" amount="400.00" contract="40"/>
            </another:payment>
     </cfdi:addments>
</cfdi:comprobante>

我需要的是一个查询,它可以提取如下所示的运动:

ID(other column Contract amount Description
39098 10 100.00 hello
39098 20 200.00 hello2
39098 30 300.00 bye
39098 40 400.00 bye2

我希望我已经足够清楚了。请在这方面真的需要帮助。

提前谢谢你。

【问题讨论】:

  • XML 元素上的那些“前缀”是 XML 命名空间 - 但是为了呈现查询以执行您想要的操作,我们需要查看这些 XML 命名空间的位置已定义(如 xmlns:cfdi - 其他可能在 XML 数据中较早的位置)
  • 嗨!谢谢你的回复,我真的没有权限检查我有这样的人: xmlns:cfdi="sat.gob.mx/cfd/3" xmlns:xsi="w3.org/2001/XMLSchema-instance" xmlns:another="pegasotecnologia.com/secfd/Schemas"

标签: sql-server xml


【解决方案1】:

您需要这样的东西 - 考虑到定义的 XML 命名空间;我无法显示确切代码,因为您没有向我们展示定义 XML 命名空间的位置(xmlns:cfdi="sat.gob.mx/cfd/3"xmlns:another="pegasotecnologia.com/secfd/Schemas"):

WITH XMLNAMESPACES('sat.gob.mx/cfd/3' AS c,
                   'pegasotecnologia.com/secfd/Schemas' AS a)
SELECT 
    ID,
    XC.value('@contract', 'int'),
    XC.value('@amount', 'decimal(16,2)'),
    xc.value('@description', 'varchar(100)')
FROM 
    dbo.YourTable
CROSS APPLY 
    XmlColumn.nodes('/c:comprobante/c:addments/a:payment/a:Movements') AS XT(XC)

如果你得到正确的 XML 命名空间,你应该得到如下输出:

【讨论】:

【解决方案2】:

首先是 XML 逻辑。

DECLARE @XML XML = 
'<cfdi:comprobante xmlns:cfdi="xxx.yyy.com" total="xxx.yyy.com" tax="xxx.yyy.com" xmlns:another="abc.com" amount="fff.net" contract="zzz.zzz" payment="ddd.com">
     <cfdi:sender information="" moreinformation=""/>
     <cfdi:receiver information="" moreinformation=""/>
     <cfdi:addments>
            <another:payment information="" moreinformation="">
                <another:Movements date="" description="hello" amount="100.00" contract="10"/>
                <another:Movements date="" description="hello2" amount="200.00" contract="20"/>
                <another:Movements date="" description="bye" amount="300.00" contract="30"/>
                <another:Movements date="" description="bye2" amount="400.00" contract="40"/>
            </another:payment>
     </cfdi:addments>
</cfdi:comprobante>';

SELECT 
  [Contract]    = f2.Nd.value('(@contract)[1]', 'int'),
  Amount        = f2.Nd.value('(@amount)[1]', 'money'),
  [Description] = f2.Nd.value('(@description)[1]', 'varchar(100)')
FROM (VALUES(@XML)) AS f(X)
CROSS APPLY f.X.nodes('//*:Movements') AS f2(Nd);

返回:

Contract    Amount     Description
----------- ---------- -----------------
10          100.00     hello
20          200.00     hello2
30          300.00     bye
40          400.00     bye2

对一张桌子需要稍作调整:

DECLARE @sometable TABLE
(
  SomeId  INT IDENTITY,
  SomeXML XML
);

INSERT @sometable VALUES(
'<cfdi:comprobante xmlns:cfdi="xxx.yyy.com" total="xxx.yyy.com" tax="xxx.yyy.com" xmlns:another="abc.com" amount="fff.net" contract="zzz.zzz" payment="ddd.com">
     <cfdi:sender information="" moreinformation=""/>
     <cfdi:receiver information="" moreinformation=""/>
     <cfdi:addments>
            <another:payment information="" moreinformation="">
                <another:Movements date="" description="hello" amount="100.00" contract="10"/>
                <another:Movements date="" description="hello2" amount="200.00" contract="20"/>
                <another:Movements date="" description="bye" amount="300.00" contract="30"/>
                <another:Movements date="" description="bye2" amount="400.00" contract="40"/>
            </another:payment>
     </cfdi:addments>
</cfdi:comprobante>'),
(
'<cfdi:comprobante xmlns:cfdi="xxx.yyy.com" total="xxx.yyy.com" tax="xxx.yyy.com" xmlns:another="abc.com" amount="fff.net" contract="zzz.zzz" payment="ddd.com">
     <cfdi:sender information="" moreinformation=""/>
     <cfdi:receiver information="" moreinformation=""/>
     <cfdi:addments>
            <another:payment information="" moreinformation="">
                <another:Movements date="" description="Hi!" amount="400.00" contract="99"/>
                <another:Movements date="" description="Sup" amount="1100.00" contract="50"/>
                <another:Movements date="" description="Boooooo" amount="3100.00" contract="30"/>
            </another:payment>
     </cfdi:addments>
</cfdi:comprobante>');

返回:

SomeId   Contract    Amount       Description
-------- ----------- ------------ --------------------
1        10          100.00       hello
1        20          200.00       hello2
1        30          300.00       bye
1        40          400.00       bye2
2        99          400.00       Hi!
2        50          1100.00      Sup
2        30          3100.00      Boooooo

【讨论】:

  • 嗨!这实际上有效,因为我必须在列上使用多个值来执行此操作,您是否知道将 xml 值声明为表上的字段的方法,例如:DECLARE @XML XML = (select g_xml_comprobante from table. id=1 的名称;
猜你喜欢
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-05
  • 2013-08-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多