我试图解析SQLServer上数据表中的xml列,将内容转换为我试图创建的dataframe中的新列。我一直在犯错误
消息9420,16级,状态1,行1
xml解析:第20行,character 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的例子(这个没有非法字符;不知道如何找到一个包含非法字符):
<?xml version="1.0" encoding="utf-8"?> <PrescriptionEvent xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <DateTimeStamp>2020-03-24T19:54:33.0169582Z</DateTimeStamp> <Outcome>true</Outcome> <OutcomeReason /> <AuditCorrelationId>3a4fb1cd-c39c-4e84-bfc4-dee98b29be2e</AuditCorrelationId> <TokenCorrelationId>d80bbd23-2e1d-44b3-9452-972b54f35cc9</TokenCorrelationId> <ActingUserId> <Value>91f78a00-ce26-4088-88eb-11x5565910d7</Value> </ActingUserId> <TenantId> <Value>00000000-0000-0000-0000-000000000000</Value> <LegacyId>10051804</LegacyId> </TenantId> <AppInstanceId> <Value>00000000-0000-0000-0000-000000000000</Value> <LegacyId>Hospital</LegacyId> </AppInstanceId> <PrescriptionReferenceId>ecf5fd42-096e-ea11-a852-005056a9ea50</PrescriptionReferenceId> <AdditionalPrescriptionReferenceId /> <ActionType>Received</ActionType> <RxSigningWorkflowActivity>RxArchive</RxSigningWorkflowActivity> <Waypoint>SMS</Waypoint> </PrescriptionEvent>
2条答案
按热度按时间yizd12fk1#
错误不是由xml中的列引起的,而是因为xml无效。它被转换成xml。
根据您的sql server版本,您应该能够通过以下方式查找错误行:
uxhixvfz2#
可以使用try\u convert查看无效xml内容的数据。下面的poc代码会有所帮助。