我对 XPath 和 XQuery 比较陌生。我正在使用存储在名为tblXML
. XML 存储在此表中caseID
。对于此示例,此值是唯一的。XML 本身存储在标记为 的列中Data
。
如果你去select * from tblXML where caseID = '12345'
你会看到这个:
caseID data
------ ------
12345 <root><patient><diagnosis preferred_name="diagnosis" tier="1">Melanoma</diagnosis> (XML file stored as blob in database)
如果您要深入研究 XML,它看起来像这样。例如,这是“12345”data
列中的 XML:caseID
<root>
<patient>
<diagnosis preferred_name="diagnosis" tier="1">Melanoma</diagnosis>
<month_of_birth preferred_name="month_of_birth" tier="1">02</month_of_birth>
<day_of_birth preferred_name="day_of_birth" tier="2">01</day_of_birth>
<year_of_birth preferred_name="year_of_birth" tier="1">1960</year_of_birth>
<new_tumor_events>
<month_of_nte preferred_name="month_of_nte" tier="1">12</month_of_nte>
<day_of_nte preferred_name="day_of_nte" tier="2">30</day_of_nte>
<year_of_nte preferred_name="year_of_nte" tier="1">1994</year_of_nte>
</new_tumor_events>
<follow_ups>
<follow_up>
<month_of_fu preferred_name="month_of_fu" tier="1">12</month_of_fu>
<day_of_fu preferred_name="day_of_fu" tier="2">31</day_of_fu>
<year_of_fu preferred_name="year_of_fu" tier="1">1995</year_of_fu>
</follow_up>
<follow_up>
<month_of_fu preferred_name="month_of_fu" tier="1">12</month_of_fu>
<day_of_fu preferred_name="day_of_fu" tier="2">31</day_of_fu>
<year_of_fu preferred_name="year_of_fu" tier="1">1996</year_of_fu>
</follow_up>
</follow_ups>
</patient>
</root>
目标:
我正在尝试为具有@Tier
属性的 XML 文档的所有级别/节点上的所有元素选择所有值"1"
。我希望看到每个值都在它自己的行中的一个名为“值”的列中输出,如下所示:
caseID Value
------ ------
12345 Melanoma
12345 02
12345 1960
12345 12
12345 1994
12345 12
12345 1995
12345 12
12345 1996
这是类似于我正在尝试编写的 SQL:
DECLARE @tier int
SET @tier = '1' --To search by tier explicitly via variable
select
x.caseID,
bar.value('(//*[@tier = sql:variable("@tier")])[1]','varchar(max)') as value
from tblXML as x
CROSS APPLY data.nodes('//*:patient') AS foo(bar)
where
x.caseID = '12345'
and x.data.value('(//@tier)[1]', 'varchar(3)') = '1'
这给了我...
case ID value
------ ------
12345 Melanoma
...但不是我正在寻找的其他行。
[1]
我认为我的困惑集中在我的 CROSS APPLY 语句中的单例和上下文节点所施加的约束上。我不确定如何获取文档中第 1 层的所有内容,而不仅仅是查询找到的第 1 层的第一个实例。
对于这个示例,我知道我的 CROSS APPLY 语句中的上下文节点专注于patient
XML 部分,但我希望能够在 XML 树的所有级别上下搜索。我知道//
for@Tier
让我可以搜索文档的所有级别,但我的上下文节点似乎在某种程度上驱动/限制了我可以搜索到文档的深度。
我的理解是我可以深入研究 XML(follow_up
也许?),然后从上到下进行搜索。但是,最深的节点将从 caseID 变为 caseID,从 XML 文档变为 XML 文档。有没有办法将我的 CROSS APPLY 语句通配到给定 XML 文档中最深的节点中,然后@Tier
在该文档中查找任何出现,然后检索其相应的值?
我意识到这种方法缺乏优雅并且没有性能。到目前为止,我还没有找到明确的文档来给我正在寻找的结果。
在此先感谢您的帮助。
编辑:我应该指定这个 SQL 将是 SQL Server 中表值函数的核心。