SQL 服务器添加?从 XML 转换时单元格值前后
SQL Server adding ? before and after cell value when converting from XML
我有一个 C# 应用程序需要一个 Excel (.xlsx
) 文件,将其转换为 XML,然后将其传递给 SQL 服务器进行转换和验证。
这多年来一直运作良好,但我现在有一个文件,其中几个单元格 ?
添加到值的开头和结尾。 XML 没有反映它们,但一定有一个隐藏的特殊字符。
这里复制了XML和T-SQL看结果:
DECLARE @x xml = '<Root>
<Row>
<ITEMNO>1</ITEMNO>
<PARTSOURCE>BUY</PARTSOURCE>
<QTY>1</QTY>
<CUSTPARTNO>10-0306</CUSTPARTNO>
<CREV>XYS</CREV>
<DESCRIPT>CAP,CER,10PF,50V,NP0,RF,0402</DESCRIPT>
<REFDESG>C96</REFDESG>
<WORKCENTER />
<ASSYNUM>18-0074-01 REV J</ASSYNUM>
<ASSYREV />
<ASSYDESC />
<CUSTNO>2519</CUSTNO>
</Row>
</Root>'
SELECT DENSE_RANK() OVER(ORDER BY
x.importBom.query('ITEMNO/text()').value('.','VARCHAR(MAX)')+
x.importBom.query('DESCRIPT/text()').value('.', 'VARCHAR(MAX)'))rowNum,
x.importBom.query('ITEMNO/text()').value('.','VARCHAR(MAX)') itemno,
UPPER(x.importBom.query('PARTSOURCE/text()').value('.', 'VARCHAR(MAX)')) partSource,
x.importBom.query('QTY/text()').value('.', 'VARCHAR(MAX)') qty,
x.importBom.query('CUSTPARTNO/text()').value('.', 'VARCHAR(MAX)') custPartNo,
x.importBom.query('CREV/text()').value('.', 'VARCHAR(MAX)')crev,
x.importBom.query('DESCRIPT/text()').value('.', 'VARCHAR(MAX)')descript,
UPPER(x.importBom.query('WORKCENTER/text()').value('.', 'VARCHAR(MAX)'))workCenter,
x.importBom.query('REFDESG/text()').value('.', 'VARCHAR(MAX)')refDesg,
x.importBom.query('CUSTNO/text()').value('.', 'VARCHAR(MAX)')custno,
x.importBom.query('ASSYNUM/text()').value('.', 'VARCHAR(MAX)')assynum,
x.importBom.query('ASSYREV/text()').value('.', 'VARCHAR(MAX)')assyrev,
x.importBom.query('ASSYDESC/text()').value('.', 'VARCHAR(MAX)')assydesc
FROM @x.nodes('/Root/Row') AS X(importBom)
OPTION (OPTIMIZE FOR(@x = NULL))
CUSTPARTNO
和 REFDESG
字段都在 SQL 服务器 table 中获得 ?
,但其他列没有。这是 CUSTPARTNO 值的服务器示例:?10-0306?
创建 XML 时,我执行以下操作以删除末尾的一些特殊字符和不需要的空格:
cellValue = cellValue.Replace("\r", "") //carriage return
.Replace("\n", " ")//new line
.Replace("\t", "")//tab
.Trim();
这不影响结果。
如何"see"隐藏特殊字符?
而且,将它们从单元格中删除以便它们不会添加到 SQL 服务器 table 中的最佳方法是什么?
不知道这是否仍然是一个悬而未决的问题,但我很好奇...
如果你用光标慢慢地浏览,你会看到在给定的地方光标不会向前移动...这就是 HEX 编辑器显示的内容
在这两种情况下,您的值都由 unicode 字符 2D20 和 2C20 构成。
2D20 是 "georgian small letter hae",2C20 是 "glagolitic capital letter yeri"。也许这可以帮助您了解它的来源。
根据 Panagiotis Kanavos 的说法,如果您将 XML 的声明更改为
,它就会起作用
DECLARE @x xml = N'<Root> ...
然后在 .value()
调用中使用 NVARCHAR
顺便说一句:这样做可以缩短您使用 .query()
然后 .value()
的查询。
SELECT DENSE_RANK() OVER(ORDER BY
x.importBom.value('ITEMNO[1]','NVARCHAR(MAX)')
+ x.importBom.value('DESCRIPT[1]', 'NVARCHAR(MAX)'))rowNum,
x.importBom.value('ITEMNO[1]','NVARCHAR(MAX)') itemno,
UPPER(x.importBom.value('PARTSOURCE[1]', 'NVARCHAR(MAX)')) partSource,
x.importBom.value('QTY[1]', 'NVARCHAR(MAX)') qty,
x.importBom.value('CUSTPARTNO[1]', 'NVARCHAR(MAX)') custPartNo,
x.importBom.value('CREV[1]', 'NVARCHAR(MAX)')crev,
x.importBom.value('DESCRIPT[1]', 'NVARCHAR(MAX)')descript,
UPPER(x.importBom.value('WORKCENTER[1]', 'NVARCHAR(MAX)'))workCenter,
x.importBom.value('REFDESG[1]', 'NVARCHAR(MAX)')refDesg,
x.importBom.value('CUSTNO[1]', 'NVARCHAR(MAX)')custno,
x.importBom.value('ASSYNUM[1]', 'NVARCHAR(MAX)')assynum,
x.importBom.value('ASSYREV[1]', 'NVARCHAR(MAX)')assyrev,
x.importBom.value('ASSYDESC[1]', 'NVARCHAR(MAX)')assydesc
FROM @x.nodes('/Root/Row') AS X(importBom)
OPTION (OPTIMIZE FOR(@x = NULL))
我有一个 C# 应用程序需要一个 Excel (.xlsx
) 文件,将其转换为 XML,然后将其传递给 SQL 服务器进行转换和验证。
这多年来一直运作良好,但我现在有一个文件,其中几个单元格 ?
添加到值的开头和结尾。 XML 没有反映它们,但一定有一个隐藏的特殊字符。
这里复制了XML和T-SQL看结果:
DECLARE @x xml = '<Root>
<Row>
<ITEMNO>1</ITEMNO>
<PARTSOURCE>BUY</PARTSOURCE>
<QTY>1</QTY>
<CUSTPARTNO>10-0306</CUSTPARTNO>
<CREV>XYS</CREV>
<DESCRIPT>CAP,CER,10PF,50V,NP0,RF,0402</DESCRIPT>
<REFDESG>C96</REFDESG>
<WORKCENTER />
<ASSYNUM>18-0074-01 REV J</ASSYNUM>
<ASSYREV />
<ASSYDESC />
<CUSTNO>2519</CUSTNO>
</Row>
</Root>'
SELECT DENSE_RANK() OVER(ORDER BY
x.importBom.query('ITEMNO/text()').value('.','VARCHAR(MAX)')+
x.importBom.query('DESCRIPT/text()').value('.', 'VARCHAR(MAX)'))rowNum,
x.importBom.query('ITEMNO/text()').value('.','VARCHAR(MAX)') itemno,
UPPER(x.importBom.query('PARTSOURCE/text()').value('.', 'VARCHAR(MAX)')) partSource,
x.importBom.query('QTY/text()').value('.', 'VARCHAR(MAX)') qty,
x.importBom.query('CUSTPARTNO/text()').value('.', 'VARCHAR(MAX)') custPartNo,
x.importBom.query('CREV/text()').value('.', 'VARCHAR(MAX)')crev,
x.importBom.query('DESCRIPT/text()').value('.', 'VARCHAR(MAX)')descript,
UPPER(x.importBom.query('WORKCENTER/text()').value('.', 'VARCHAR(MAX)'))workCenter,
x.importBom.query('REFDESG/text()').value('.', 'VARCHAR(MAX)')refDesg,
x.importBom.query('CUSTNO/text()').value('.', 'VARCHAR(MAX)')custno,
x.importBom.query('ASSYNUM/text()').value('.', 'VARCHAR(MAX)')assynum,
x.importBom.query('ASSYREV/text()').value('.', 'VARCHAR(MAX)')assyrev,
x.importBom.query('ASSYDESC/text()').value('.', 'VARCHAR(MAX)')assydesc
FROM @x.nodes('/Root/Row') AS X(importBom)
OPTION (OPTIMIZE FOR(@x = NULL))
CUSTPARTNO
和 REFDESG
字段都在 SQL 服务器 table 中获得 ?
,但其他列没有。这是 CUSTPARTNO 值的服务器示例:?10-0306?
创建 XML 时,我执行以下操作以删除末尾的一些特殊字符和不需要的空格:
cellValue = cellValue.Replace("\r", "") //carriage return
.Replace("\n", " ")//new line
.Replace("\t", "")//tab
.Trim();
这不影响结果。
如何"see"隐藏特殊字符?
而且,将它们从单元格中删除以便它们不会添加到 SQL 服务器 table 中的最佳方法是什么?
不知道这是否仍然是一个悬而未决的问题,但我很好奇...
如果你用光标慢慢地浏览,你会看到在给定的地方光标不会向前移动...这就是 HEX 编辑器显示的内容
在这两种情况下,您的值都由 unicode 字符 2D20 和 2C20 构成。 2D20 是 "georgian small letter hae",2C20 是 "glagolitic capital letter yeri"。也许这可以帮助您了解它的来源。
根据 Panagiotis Kanavos 的说法,如果您将 XML 的声明更改为
,它就会起作用DECLARE @x xml = N'<Root> ...
然后在 .value()
调用中使用 NVARCHAR
顺便说一句:这样做可以缩短您使用 .query()
然后 .value()
的查询。
SELECT DENSE_RANK() OVER(ORDER BY
x.importBom.value('ITEMNO[1]','NVARCHAR(MAX)')
+ x.importBom.value('DESCRIPT[1]', 'NVARCHAR(MAX)'))rowNum,
x.importBom.value('ITEMNO[1]','NVARCHAR(MAX)') itemno,
UPPER(x.importBom.value('PARTSOURCE[1]', 'NVARCHAR(MAX)')) partSource,
x.importBom.value('QTY[1]', 'NVARCHAR(MAX)') qty,
x.importBom.value('CUSTPARTNO[1]', 'NVARCHAR(MAX)') custPartNo,
x.importBom.value('CREV[1]', 'NVARCHAR(MAX)')crev,
x.importBom.value('DESCRIPT[1]', 'NVARCHAR(MAX)')descript,
UPPER(x.importBom.value('WORKCENTER[1]', 'NVARCHAR(MAX)'))workCenter,
x.importBom.value('REFDESG[1]', 'NVARCHAR(MAX)')refDesg,
x.importBom.value('CUSTNO[1]', 'NVARCHAR(MAX)')custno,
x.importBom.value('ASSYNUM[1]', 'NVARCHAR(MAX)')assynum,
x.importBom.value('ASSYREV[1]', 'NVARCHAR(MAX)')assyrev,
x.importBom.value('ASSYDESC[1]', 'NVARCHAR(MAX)')assydesc
FROM @x.nodes('/Root/Row') AS X(importBom)
OPTION (OPTIMIZE FOR(@x = NULL))