我有一个包含一个 XML 列的 SQL 表,我想查询 XML 并获取
id/@extension
以及所有 observation/code
的列表。但是它总是返回空结果。我已经隔离了一个包含代表性测试数据的示例表,请参见下文
CREATE TABLE study123 (
ID integer,
Title varchar(25),
STXML XML
);
INSERT INTO study123 (
ID,
Title,
STXML
) VALUES
(1, 'ST_Cardio', '<MeasurementDocument xmlns="urn:hl7-org:v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<id extension="68c65a01-2188-486c-adde-a854453ff817" />
<code code="ST_Cardio" displayName="CardioLife60+" />
<title>CardioLife 60+</title>
<text>Prospective validation of CardioLife algorithms age 60+</text>
<component>
<section>
<entry typeCode="DRIV">
<observation classCode="OBS" moodCode="CRT">
<code code="TMPL_1120000364" displayName="CV TEE/CARDIO DAILYLOG" />
</observation>
</entry>
<entry typeCode="DRIV">
<observation classCode="OBS" moodCode="CRT">
<code code="TMPL_1120000365" displayName="CV TEE/CARDIO VITAL SIGNS CHECKLIST" />
</observation>
</entry>
</section>
</component>
</MeasurementDocument>'),
(2, 'ST_Cardio', '<MeasurementDocument xmlns="urn:hl7-org:v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<id extension="a3be767f-1315-4e2b-ab4e-11a238d7f9a1" />
<code code="ST_Diabetics" displayName="DiabeticsObs" />
<title>Diabetics Observation 2023-2024</title>
<text>Diabetics Observation 2023-2024 Extended II</text>
<component>
<section>
<entry typeCode="DRIV">
<observation classCode="OBS" moodCode="CRT">
<code code="TMPL_1173900045" displayName="CVR PHYSIC DIABETICS" />
</observation>
</entry>
<entry typeCode="DRIV">
<observation classCode="OBS" moodCode="CRT">
<code code="TMPL_1177400741" displayName="CVR DIABETICS OBSERVATIONWEEK" />
</observation>
</entry>
<entry typeCode="DRIV">
<observation classCode="OBS" moodCode="CRT">
<code code="TMPL_1189600034" displayName="CVR DIABETICS REVALIDATION CHECKLIST" />
</observation>
</entry>
</section>
</component>
</MeasurementDocument>
');
这是我尝试过的,但这只会给出所有空的 NULL 结果。当我尝试仅查询每个研究中的单个 ID 和文本描述时,列为 NULL
-- test columns are all NULL(?)
SELECT
ID,
Title,
STXML,
STXML.value('(/MeasurementDocument/id/@extension)[1]', 'nvarchar(100)') AS test_id,
STXML.value('(/MeasurementDocument/title)[1]', 'nvarchar(100)') AS test_title,
STXML.value('(/MeasurementDocument/text)[1]', 'nvarchar(100)') AS test_text
FROM
study123
当我尝试查询每个研究的所有模板时,结果为空,即使第一个有 2 个模板,第二个有 3 个模板。
-- no records, empty result
select * from
(select
ID,
Title,
TheTemplate.value('(./observation/code/@code)[1]', 'varchar(1000)') as tmpl_code
from
study123 CROSS APPLY
STXML.nodes('MeasurementDocument/component/section/entry[@typeCode="DRIV"]/observation') AS AllTemplates(TheTemplate)
) as Result
我尝试搜索示例并询问 ChatGPT,但我感觉查询 XML 的 SQL Server 示例并不能很好地代表现实世界的 xml 示例,或者它们缺少某些内容(?)。
您需要使用
WITH XMLNAMESPACES
添加默认命名空间,并且您已将 observation
节点加倍。
您还可以避免用另一个
CROSS APLY nodes
引用根节点。
WITH XMLNAMESPACES (DEFAULT 'urn:hl7-org:v3')
SELECT
ID,
Title,
doc.value('(id/@extension)[1]', 'nvarchar(100)') AS test_id,
doc.value('(title/text())[1]', 'nvarchar(100)') AS test_title,
doc.value('(text/text())[1]', 'nvarchar(100)') AS test_text,
TheTemplate.value('(code/@code)[1]', 'nvarchar(1000)') as tmpl_code
from
study123 s
CROSS APPLY
s.STXML.nodes('MeasurementDocument') x1(doc)
CROSS APPLY
x1.doc.nodes('component/section/entry[@typeCode="DRIV"]/observation') AS AllTemplates(TheTemplate);