Extraiga valores de datos de la columna XML en la base de datos de SQL Server

CorePress2024-01-24  8

Tengo una base de datos de SQL Server con una tabla que contiene una columna XML. Quiero extraer datos de él, pero estamos usando un prefijo en el nombre.

Aquí tienes un ejemplo:

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

Lo que necesito es una consulta que extraiga los movimientos que se parecen a estos:

ID (otra columna Contrato cantidad Descripción 39098 10 100.00 Hola 39098 20 200.00 hola2 39098 30 300.00 adiós 39098 40 400.00 adios2

Espero haber sido lo suficientemente claro. Por favor, realmente necesito ayuda con esto.

Gracias de antemano.

1

Esose "prefijos" en los elementos XML hay espacios de nombres XML, pero para presentar una consulta que haga lo que desea, necesitaremos ver dónde están definidos esos espacios de nombres XML (como xmlns:cfdi; los otros probablemente estén en algún lugar anterior del archivo XML). datos)

-marc_s

26/03/2021 a las 19:21

¡Hola! gracias por la respuesta, realmente no tengo permiso para revisar esos los tengo así: xmlns:cfdi="sat.gob.mx/cfd/3" xmlns:xsi="w3.org/2001/XMLSchema-instance"xmlns:another="pegasotecnología.com/secfd/Schemas"

-Alejandro Malagón

26/03/2021 a las 22:24



------------------------------------

Necesita algo como esto: teniendo en cuenta los espacios de nombres XML definidos; No puedo mostrar el código exacto, ya que no nos has mostrado el lugar donde están definidos tus namespaces XML (xmlns:cfdi="sat.gob.mx/cfd/3" y xmlns:another="pegasotecnologia.com/ secfd/Esquemas"):

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)

Si obtienes los espacios de nombres XML correctos, deberías obtener un resultado similar a este:

2

¡Hola! gracias por la respuesta, realmente no tengo permiso para revisar esos los tengo así: xmlns:cfdi="sat.gob.mx/cfd/3" xmlns:xsi="w3.org/2001/XMLSchema-instance" xmlns:another="pegasotecnología.com/secfd/Schemas"

-Alejandro Malagón

26/03/2021 a las 22:25

1

Para mí, esta parece la respuesta correcta. Sugerencia: no olvide incluir un punto y coma antes de la declaración with.

- Phil Blackburn

27/03/2021 a las 12:49



------------------------------------

Primero la lógica 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);

Devoluciones:

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

Contra una tabla requiere un pequeño ajuste:

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>');

Devoluciones:

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

1

1

¡Hola! Esto realmente ha funcionado, porque tengo que hacer esto con varios valores en la columna, ¿conoces una forma de declarar el valor xml como el campo en la tabla, como poner esto: DECLARE @XML XML = (select g_xml_comprobante from table. nombre donde id=1;

-Alejandro Malagón

27 de marzo de 2021 a las 0:48

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare