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 服务器都会忽略此声明,但您无法通过 NVARCHAR
将 UTF-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);
我正在尝试将 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 服务器都会忽略此声明,但您无法通过 NVARCHAR
将 UTF-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);