XML解析-错误消息为“0”;非法XML字符“;对于未知行&;SQL Server表中的列

XML解析-错误消息为“0”;非法XML字符“;对于未知行&;SQL Server表中的列,sql,sql-server,xml,xml-parsing,ssms,Sql,Sql Server,Xml,Xml Parsing,Ssms,我试图解析SQL Server上数据表中的xml列,将内容转换为我试图创建的数据框架中的新列。我一直在犯错误 Msg 9420,第16级,状态1,第1行 XML解析:第20行,字符2005,非法XML字符 我不知道如何解决这个问题。并非每行的xml列中都存在此非法字符 我的SQL代码能够解析570000行,直到它遇到一个带有非法字符的行并停止运行。假设我的WHERE子句解析并提取1200000行。因此,代码能够在退出之前成功地解析所需行的不到一半。xml列存储为varchar,因此我确实需要转换

我试图解析SQL Server上数据表中的xml列,将内容转换为我试图创建的数据框架中的新列。我一直在犯错误

Msg 9420,第16级,状态1,第1行
XML解析:第20行,字符2005,非法XML字符

我不知道如何解决这个问题。并非每行的xml列中都存在此非法字符

我的SQL代码能够解析570000行,直到它遇到一个带有非法字符的行并停止运行。假设我的WHERE子句解析并提取1200000行。因此,代码能够在退出之前成功地解析所需行的不到一半。xml列存储为varchar,因此我确实需要转换为xml以解析内容

这段SQL代码确实有效。它处理原始数据,其中包含生产数据和虚假测试数据。我能够访问仅用于生产的表,正是在这个表中我遇到了错误。在将数据传输到仅生产表时,数据一定发生了某些情况

我试着在帖子中寻找一些可以帮助我的东西,但什么也找不到。我不知道如何在我正在处理的1.2M记录中找到错误,也不知道是哪个解析列导致了问题。解析算法是否有办法跳过有问题的行并继续解析剩余的记录

我的代码是:

SELECT [Id]
      ,[EventDateTime]
      ,[TenantId]
      ,[EventType]
      ,[EventXml]
      ,[InsertDateTime]
      ,[AppInstanceId]
      ,[TokenCorrelationId]
      ,[AuditCorrelationId]
      ,[AuditId]
      ,CAST([EventXml] as XML).value('/PrescriptionEvent [1]/DateTimeStamp[1]','NVARCHAR(max)') AS xml_DateTimeStamp 
      ,UPPER(CAST([EventXml] as XML).value('/PrescriptionEvent[1]/AuditCorrelationId[1]','NVARCHAR(max)')) AS xml_AuditCorrelationId
      ,UPPER(CAST([EventXml] as XML).value('/PrescriptionEvent[1]/TokenCorrelationId[1]','NVARCHAR(max)')) AS xml_TokenCorrelationId
      ,UPPER(CAST([EventXml] as XML).value('/PrescriptionEvent[1]/ActingUserId[1]/Value[1]','NVARCHAR(max)')) AS xml_ActingUserId
      ,UPPER(CAST([EventXml] as XML).value('/PrescriptionEvent[1]/ActingUserId[1]/LegacyId[1]','NVARCHAR(max)')) AS xml_ActingUserId_LegacyId
      ,UPPER(CAST([EventXml] as XML).value('/PrescriptionEvent[1]/TenantId[1]/Value[1]','NVARCHAR(max)')) AS xml_TenantId
      ,UPPER(CAST([EventXml] as XML).value('/PrescriptionEvent[1]/TenantId[1]/LegacyId[1]','NVARCHAR(max)')) AS xml_TenantId_LegacyId
      ,UPPER(CAST([EventXml] as XML).value('/PrescriptionEvent[1]/AppInstanceId[1]/Value[1]','NVARCHAR(max)')) AS xml_AppInstanceId
      ,UPPER(CAST([EventXml] as XML).value('/PrescriptionEvent[1]/AppInstanceId[1]/LegacyId[1]','NVARCHAR(max)')) AS xml_AppInstanceId_LegacyId
      ,UPPER(CAST([EventXml] as XML).value('/PrescriptionEvent[1]/ActionType[1]','NVARCHAR(max)')) AS xml_ActionType
      ,UPPER(CAST([EventXml] as XML).value('/PrescriptionEvent[1]/Outcome[1]','NVARCHAR(max)')) AS xml_Outcome
      ,UPPER(CAST([EventXml] as XML).value('/PrescriptionEvent[1]/OutcomeReason[1]','NVARCHAR(max)')) AS xml_OutcomeReason
      ,UPPER(CAST([EventXml] as XML).value('/PrescriptionEvent[1]/RxSigningWorkflowActivity[1]','NVARCHAR(max)')) AS xml_RxSigningWorkflowActivity
      ,UPPER(CAST([EventXml] as XML).value('/PrescriptionEvent[1]/Waypoint[1]','NVARCHAR(max)')) AS xml_Waypoint
      ,UPPER(CAST([EventXml] as XML).value('/PrescriptionEvent[1]/PrescriptionReferenceId[1]','NVARCHAR(max)')) AS xml_PrescriptionReferenceId
  FROM [EpcsAuditDB].[dbo].[EpcsAuditEventData]
  WHERE [EventType] = 4 AND [EventDateTime] >= '2020-03-24'
xml示例(此示例没有非法字符;不知道如何查找包含非法字符的示例):

2020-03-24T19:54:33.0169582Z true 3a4fb1cd-c39c-4e84-bfc4-dee98b29be2e d80bbd23-2e1d-44b3-9452-972b54f35cc9 91f78a00-ce26-4088-88eb-11x5565910d7 00000000-0000-0000-0000-00000000-1005180400000-0000-0000-00000000医院ecf5fd42-096e-ea11-a852-005056a9ea50收到RX存档短信

错误不是由XML中的列引起的,而是因为XML无效。它被转换为XML

根据您的sql server版本,您应该能够通过以下方式找到错误行:

select EventXml 
from [EpcsAuditDB].[dbo].[EpcsAuditEventData]
where try_cast([EventXml] as XML) is null

错误不是由XML中的列引起的,而是因为XML无效。它被转换为XML

根据您的sql server版本,您应该能够通过以下方式找到错误行:

select EventXml 
from [EpcsAuditDB].[dbo].[EpcsAuditEventData]
where try_cast([EventXml] as XML) is null

您可以使用TRY_CONVERT查看无效xml内容的数据。下面的POC代码将很有帮助

DECLARE@tableWithxml表(id int,xmlcontent varchar(500))
插入@tableWithxml

值(1,'1'),(2,您可以使用TRY_CONVERT查看无效xml内容的数据。下面的POC代码将非常有用

DECLARE@tableWithxml表(id int,xmlcontent varchar(500))
插入@tableWithxml

值(1,'1'),(2,'您要做的第一件事是使用CTE,这样您只需对XML进行转换,并提取第一个PrescriptionEvent节点一次。这将简化事情,并可能在某种程度上加快速度。您要做的第一件事是使用CTE,这样您只需对XML进行转换,并提取第一个PrescriptionEvent节点一次。T这会简化事情,可能会加快速度。谢谢你的建议和CTE建议。这非常有帮助,@TomCThank你的建议和CTE建议。这非常有帮助,@TomCThank你。这非常有帮助。谢谢。这非常有帮助
+----+------------+
| id | xmlcontent |
+----+------------+
|  2 | <x 1</x>   |
+----+------------+