SQL Server正在添加?从XML转换时的前后单元格值

SQL Server正在添加?从XML转换时的前后单元格值,xml,excel,sql-server-2014,Xml,Excel,Sql Server 2014,我有一个C应用程序,它获取Excel(.xlsx)文件,将其转换为XML,并将其传递给SQL Server进行转换和验证 这已经运行了好几年了,但我现在有一个文件,其中有几个单元格被添加到值的开始和结束处。XML不反映它们,但必须有一个特殊字符隐藏在视图中 以下是XML和T-SQL的副本以查看结果: DECLARE @x xml = '<Root> <Row> <ITEMNO>1</ITEMNO> <PARTSOURCE>BU

我有一个C应用程序,它获取Excel(
.xlsx
)文件,将其转换为XML,并将其传递给SQL Server进行转换和验证

这已经运行了好几年了,但我现在有一个文件,其中有几个单元格被添加到值的开始和结束处。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))
这不会影响结果

如何“看到”隐藏的特殊字符


还有,从单元格中删除它们以便不将它们添加到SQL Server表中的最佳方法是什么?

不知道这是否仍然是一个悬而未决的问题,但我很好奇

如果你慢慢地用光标走过去,你会发现在给定的位置,光标不会向前移动。。。这就是十六进制编辑器显示的内容

在这两种情况下,值都由unicode字符2D20和2C20构成框架。 2D20是“格鲁吉亚小写字母hae”,2C20是“Glagolic大写字母yeri”。也许这有助于你理解这是从哪里来的

根据Panagiotis Kanavos的说法,如果将XML的声明更改为

DECLARE @x xml = N'<Root> ...

@pnuts,我知道用户可以修剪值(它可以工作),但我不能依赖用户在上传之前总是这样做。这一点尤其正确,因为用户在上传之前不会在Excel中看到它来知道他们需要运行修剪(或任何)功能。我收回,修剪不起作用。我不得不写一个奇特的excel公式=MID(B2,2,LEN(B2)-2)。这将在上载之前删除未知字符。我仍然想在我的代码中阻止它,但这暂时起作用。您的初始文本包含无法转换为ASCII(VARCHAR)的不可见Unicode字符。如果您使用NVARCHAR(MAX),就不会有问题。是否需要这些Unicode值是另一个问题matter@PanagiotisKanavos正如我在下面告诉你的,使用NVARCHAR不会改变效果。看看,我贴了一些代码。。。但我对unicode字符没有经验。您认为设置
语言
选项可能会改变某些内容吗?@Shnugo实际上是这样,但原始文本也需要是Unicode。实际上,它是ASCII,即xml文本不是以
N
开头。添加此选项至少可以解决转换问题。实际上,OP确实转换为VARCHAR(MAX),这可能是导致问题的原因。如果改为使用NVARCHAR(MAX),则会保留角色。然而,这些字符是否是需要的,则是另一回事。它们不能被修剪,因为它们不是whitespace@PanagiotisKanavos,是的,我试过这个,但是使用NVARCHAR时也会出现相同的效果…这是因为字符串文字是ASCII,它不是以N开头的。数据从声明开始就被破坏了。将其更改为
DECLARE@x xml=N'
将删除
characters@PanagiotisKanavos,谢谢你把我打得一败涂地!谢谢你们两位!!!。至少它没有显示出你想要的东西?不再有没有办法删除这些和任何其他“隐藏”字符?
DECLARE @x xml = N'<Root> ...
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))