SQL 服务器从 XML 文件插入

SQL Server insert from a XML file

我正在尝试将 XML 文件中的信息插入 SQL 服务器中的临时 table,但无法获取。

首先我声明了一个 table 变量,然后我在这个 table 中插入,值来自 XML 文件,最后我 select 来自 table 变量的数据应该在之前插入信息,但是 select 只是 returns 一个没有错误的空结果。

有什么想法吗?

这是XML

<?xml version="1.0" encoding="UTF-8"?>
<cfdi:Comprobante Moneda="MXN" NumCtaPago="3746" LugarExpedicion="something" metodoDePago="03" tipoDeComprobante="ingreso" total="434.30" descuento="0.00" subTotal="402.14" 
 noCertificado="00001000000403736552" formaDePago="pago en una sola exhibición" sello="something" fecha="something" folio="something" serie="something" version="3.2" xsi:schemaLocation="http://something http://something" xmlns:xsi="http://something" xmlns:cfdi="http://something">

<cfdi:Addenda xsi:schemaLocation="https://something" xmlns:xsi="http://something" xmlns="https://something">
<ADDENDABENAVIDES>
<HEADERFACTURA INTNOTAENTRADA="something" STRREMISIONID="something" STRCLAVEFACTREM= "something" FLTIEPSFACTURA="something" FLTIVADESCUENTO="something" FLTDESCUENTOFACTURA="something" FLTBRUTOFACTURA="something" FLTIVAFACTURA="something" FLTNETOFACTURA="something" STRALMACENID="something" STRCENTROLOGISTICOID="something" DTMFECHAFACTURA="something" INTNOREGISTRO="something" STRFOLIO="something" STRSERIE="something" INTBODEGAID="something" INTMAYORISTAID="something" STRNUMEROPROVEEDOR="something"/>
<DETALLEFACTURA>
  <DETALLEPRODUCTO />
</DETALLEFACTURA>
</ADDENDABENAVIDES>
</cfdi:Addenda>
</cfdi:Comprobante>   

这是来自SQL

DECLARE @HEADERFACTURA TABLE
(
     Id int IDENTITY(1,1),
     [INTNOTAENTRADA] int,
     [STRREMISIONID] NVARCHAR(max),
     [STRCLAVEFACTREM] NVARCHAR(max), 
     [FLTIEPSFACTURA] decimal(10,2),
     [FLTIVADESCUENTO] decimal(10,2),
     [FLTDESCUENTOFACTURA] decimal(10,2),
     [FLTBRUTOFACTURA] decimal(10,2),
     [FLTIVAFACTURA] decimal(10,2),
     [FLTNETOFACTURA] decimal(10,2),
     [STRALMACENID] int,
     [STRCENTROLOGISTICOID] NVARCHAR(max),
     [DTMFECHAFACTURA] NVARCHAR(max),
     [INTNOREGISTRO] int,
     [STRFOLIO] int,
     [STRSERIE] NVARCHAR(max),
     [INTBODEGAID] int,
     [INTMAYORISTAID] int,
     [STRNUMEROPROVEEDOR] NVARCHAR(max)
)

;with xmlnamespaces('http://something' as cfdi)
INSERT INTO @HEADERFACTURA ([INTNOTAENTRADA], [STRREMISIONID],
                            [STRCLAVEFACTREM], [FLTIEPSFACTURA],
                            [FLTIVADESCUENTO], [FLTDESCUENTOFACTURA],
                            [FLTBRUTOFACTURA], [FLTIVAFACTURA],
                            [FLTNETOFACTURA], [STRALMACENID],
                            [STRCENTROLOGISTICOID], [DTMFECHAFACTURA],
                            [INTNOREGISTRO], [STRFOLIO],
                            [STRSERIE], [INTBODEGAID],
                            [INTMAYORISTAID], [STRNUMEROPROVEEDOR])
SELECT
    X.Solicitud.query('INTNOTAENTRADA').value('.', 'int'),
    X.Solicitud.query('STRREMISIONID').value('.', 'nvarchar(50)'),
    X.Solicitud.query('STRCLAVEFACTREM').value('.', 'nvarchar(50)'),
    X.Solicitud.query('FLTIEPSFACTURA').value('.', 'decimal(10,2)'),
    X.Solicitud.query('FLTIVADESCUENTO').value('.', 'decimal(10,2)'),
    X.Solicitud.query('FLTDESCUENTOFACTURA').value('.', 'decimal(10,2)'),
    X.Solicitud.query('FLTBRUTOFACTURA').value('.', 'decimal(10,2)'),
    X.Solicitud.query('FLTIVAFACTURA').value('.', 'decimal(10,2)'),
    X.Solicitud.query('FLTNETOFACTURA').value('.', 'decimal(10,2)'),
    X.Solicitud.query('STRALMACENID').value('.', 'int'),
    X.Solicitud.query('STRCENTROLOGISTICOID').value('.', 'nvarchar(50)'),
    X.Solicitud.query('DTMFECHAFACTURA').value('.', 'nvarchar(50)'),
    X.Solicitud.query('INTNOREGISTRO').value('.', 'int'),
    X.Solicitud.query('STRFOLIO').value('.', 'int'),
    X.Solicitud.query('STRSERIE').value('.', 'nvarchar(50)'),
    X.Solicitud.query('INTBODEGAID').value('.', 'int'),
    X.Solicitud.query('INTMAYORISTAID').value('.', 'int'),
    X.Solicitud.query('STRNUMEROPROVEEDOR').value('.', 'nvarchar(50)')
 FROM  
     (SELECT 
          CAST (X AS XML)
      FROM 
          OPENROWSET (BULK 'C:\aa.xml', SINGLE_BLOB) AS T(X)
     ) AS T(X)
CROSS APPLY 
     x.nodes('/cfdi:Comprobante/cfdi:Addenda/ADDENDABENAVIDES/HEADERFACTURA') AS X(Solicitud);

SELECT *
FROM @HEADERFACTURA

提前致谢。

您的输入 xml 中有特定命名空间和默认命名空间。修复以下行,您将得到结果:

CROSS APPLY x.nodes('//cfdi:Comprobante/cfdi:Addenda/*:ADDENDABENAVIDES/*:HEADERFACTURA') AS X(Solicitud);

请注意,您的示例中的查询仍然会失败,因为您查询的所有属性都是字符串,并且您的查询正在将它们转换为类型。

另请注意,您可以按照此示例简化每个属性语句: X.Solicitud.query('STRNUMEROPROVEEDOR').value('.', 'nvarchar(50)') 变成 X.Solicitud.value('@STRNUMEROPROVEEDOR', 'nvarchar(50)')

最后,请注意您的 xml 是 <?xml version="1.0" encoding="UTF-8"?>;我相信它应该是 <?xml version="1.0" encoding="UTF-16"?> 因为你使用的是重音字符。您的 XML 文件可能无法解析。

在您尝试为 XML 提供 清理后的 数据时,您做得太过分了...

应该是数字的值(例如 int)显示为“Something”,实际上 everything 显示为 “something”。 =39=]...

另一个问题是,您的命名空间都设置为相同的 URL。

看看你的 XML 的这个(高度浓缩的)样本(默认命名空间在第二层!):

<?xml version="1.0" encoding="UTF-8"?>  
<cfdi:Comprobante xmlns:cfdi="http://something" Moneda="MXN">
  <cfdi:Addenda xmlns="https://Default">
    <ADDENDABENAVIDES>
      <HEADERFACTURA INTNOTAENTRADA="123" STRREMISIONID="something" />
      <DETALLEFACTURA>
        <DETALLEPRODUCTO />
      </DETALLEFACTURA>
    </ADDENDABENAVIDES>
  </cfdi:Addenda>
</cfdi:Comprobante>

还有一个问题是,您的 XML 文件以 encoding="utf-8" 的声明开头,但您的内容包含特殊字符。在任何情况下,SQL 服务器都会忽略此声明,但您无法通过 NVARCHARUTF-8 读入 XML。因此我将其读入 NVARCHAR(MAX),调用 REPLACE 引入 utf-16 并将其转换为 XML。

下一点是,您想读取属性,但您尝试将它们作为元素找到。

您可以在这里查询:

;WITH XMLNAMESPACES(DEFAULT 'https://Default'
                           ,'http://something' AS cfdi)

SELECT
    --An attribute from <cfdi:Comprobante>
    T.X.value('(/cfdi:Comprobante/@Moneda)[1]','nvarchar(max)') AS Moneda,
    --Many attributes in <HEADERFACTURA>
    X.Solicitud.value('@INTNOTAENTRADA', 'int') AS INTNOTAENTRADA,
    X.Solicitud.value('@STRREMISIONID', 'nvarchar(50)') AS STRREMISIONID
 FROM  
     (SELECT 
          CAST(REPLACE(CAST (X AS NVARCHAR(MAX)),'utf-8','utf-16') AS XML)
      FROM 
          OPENROWSET (BULK 'C:\aa.xml', SINGLE_CLOB) AS T(X)
     ) AS T(X)
CROSS APPLY 
     x.nodes('/cfdi:Comprobante/cfdi:Addenda/ADDENDABENAVIDES/HEADERFACTURA') AS X(Solicitud);