我有一个名为v_EpisodeAudit的表,其中一个名为EventData的列包含XML数据。 XML数据因行而异,因此一列记录可能包含此列中的XML数据,如下所示:
<AddMDMDocument>
<EpisodeMDMId>282521</EpisodeMDMId>
<OncologyReferral>0</OncologyReferral>
<SpecialPalliativeReferral>0</SpecialPalliativeReferral>
<SurgeonReferral>0</SurgeonReferral>
<MDMReport>0</MDMReport>
<GPReferral>0</GPReferral>
<GPReferralApproval>0</GPReferralApproval>
<GeneralPalliativeCare>0</GeneralPalliativeCare>
<AuditLogin>mkell010</AuditLogin>
<AuditTrust>4</AuditTrust>
<Error />
</AddMDMDocument>
而另一行可能包含以下XML数据:
<CloseEpisode>
<EpisodeId>652503</EpisodeId>
<TrackingStatusId>9</TrackingStatusId>
<TrackingClosureReason>100</TrackingClosureReason>
<DateOfTrackingClosure>Sep 25 2017 12:37PM</DateOfTrackingClosure>
<AuditLogin>ccass001</AuditLogin>
<AuditTrust>1</AuditTrust>
<Error />
</CloseEpisode>
还有不同类型/配置的XML数据。今天早上我已经阅读了大约20个不同的来源,试图找出如何搜索本专栏中的XML数据以获取CloseEpisode XML中的特定EpisodeId,而我无法在生活中找到它。任何人都可以帮助我查找将在此列中找到指定的EpisodeId的查询吗?
答案 0 :(得分:4)
可以非常一般地查询XML。一些方法:
DECLARE @v_EpisodeAudit TABLE(ID INT IDENTITY, [EventData] XML);
INSERT INTO @v_EpisodeAudit VALUES
(N'<AddMDMDocument>
<EpisodeMDMId>282521</EpisodeMDMId>
<OncologyReferral>0</OncologyReferral>
<SpecialPalliativeReferral>0</SpecialPalliativeReferral>
<SurgeonReferral>0</SurgeonReferral>
<MDMReport>0</MDMReport>
<GPReferral>0</GPReferral>
<GPReferralApproval>0</GPReferralApproval>
<GeneralPalliativeCare>0</GeneralPalliativeCare>
<AuditLogin>mkell010</AuditLogin>
<AuditTrust>4</AuditTrust>
<Error />
</AddMDMDocument>')
,(N'<CloseEpisode>
<EpisodeId>652503</EpisodeId>
<TrackingStatusId>9</TrackingStatusId>
<TrackingClosureReason>100</TrackingClosureReason>
<DateOfTrackingClosure>Sep 25 2017 12:37PM</DateOfTrackingClosure>
<AuditLogin>ccass001</AuditLogin>
<AuditTrust>1</AuditTrust>
<Error />
</CloseEpisode>');00
- 这将返回第二级的第一个节点
SELECT ID
,vEA.[EventData].value(N'local-name(/*[1]/*[1])',N'nvarchar(max)') AS NodeName
,vEA.[EventData].value(N'/*[1]/*[1]/text()[1]',N'nvarchar(max)') AS NodeValue
FROM @v_EpisodeAudit AS vEA
- 这将返回sevond级别的所有节点,并使用WHERE
和LIKE
来查找Episode..Id元素
SELECT ID
,SecondLevelNode.Nd.value(N'local-name(.)',N'nvarchar(max)') AS NodeName
,SecondLevelNode.Nd.value(N'text()[1]',N'nvarchar(max)') AS NodeValue
FROM @v_EpisodeAudit AS vEA
OUTER APPLY vEA.[EventData].nodes(N'/*/*') AS SecondLevelNode(Nd)
WHERE SecondLevelNode.Nd.value(N'local-name(.)',N'nvarchar(max)') LIKE 'Episode%' --or LIKE 'Episode%Id'
- 类似但在XQuery级别上过滤
SELECT ID
,SecondLevelNode.Nd.value(N'local-name(.)',N'nvarchar(max)') AS NodeName
,SecondLevelNode.Nd.value(N'text()[1]',N'nvarchar(max)') AS NodeValue
FROM @v_EpisodeAudit AS vEA
OUTER APPLY vEA.[EventData].nodes(N'/*/*[substring(local-name(),1,7)="Episode"]') AS SecondLevelNode(Nd)
答案 1 :(得分:3)
使用xml查询功能
select EventData.value('(/CloseEpisode/EpisodeId)[1]','int')
from v_EpisodeAudit
where EventData.value('local-name(/*[1])','varchar(100)')='CloseEpisode'
或者
select EventData
from @v_EpisodeAudit
where EventData.value('(/CloseEpisode/EpisodeId)[1]','int')=652503
取决于你想要做什么。
如果您不知道根节点名称,可以使用
select EventData.value('(//EpisodeId)[1]','int')
from v_EpisodeAudit
where EventData.exist('//EpisodeId')=1
请参阅https://docs.microsoft.com/en-us/sql/t-sql/xml/value-method-xml-data-type